**
(ද්විත්ව තාරකාව) සහ *
(තාරකාව) පරාමිතීන් සඳහා කරන්නේ කුමක්ද?
ඒවා පිළිගැනීමට කාර්යයන් නිර්වචනය කිරීමට සහ පරිශීලකයින්ට ඕනෑම තර්ක, ස්ථානීය ( *
) සහ යතුරු පද ( **
) සම්මත කිරීමට ඉඩ දෙයි .
කාර්යයන් නිර්වචනය කිරීම
*args
ඕනෑම විකල්ප ස්ථානීය තර්ක (පරාමිතීන්) සඳහා ඉඩ ලබා දේ args
.
**kwargs
නම් කරන ලද විධානයක් තුළ ඇති ඕනෑම විකල්ප මූල පද තර්ක (පරාමිතීන්) සඳහා ඉඩ ලබා දේ kwargs
.
ඔබට හැකි (හා විය යුතු) ඕනෑම සුදුසු නමක් තෝරා, නමුත් තර්ක විශේෂිත නොවන semantics විය කිරීම සඳහා බලාපොරොත්තුව වන්නේ නම්, args
හා kwargs
සම්මත නම් වේ.
පුළුල් කිරීම, ඕනෑම තර්ක ගණනාවක් සම්මත කිරීම
ඔබ ද භාවිතා කළ හැකිය *args
සහ **kwargs
පිළිවෙළින්, ලැයිස්තු (හෝ ඕනෑම iterable) සහ dicts (හෝ ඕනෑම සිතියම්) සිට පරාමිතීන් සම්මත කිරීමට.
පරාමිතීන් ලබා ගැනීමේ ශ්රිතය ඒවා පුළුල් වන බව දැන සිටිය යුතු නොවේ.
උදාහරණයක් ලෙස, පයිතන් 2 හි xrange පැහැදිලිවම අපේක්ෂා නොකරයි *args
, නමුත් එය පූර්ණ සංඛ්යා 3 ක් තර්ක ලෙස ගන්නා බැවින්:
>>> x = xrange(3) # create our *args - an iterable of 3 integers
>>> xrange(*x) # expand here
xrange(0, 2, 2)
තවත් උදාහරණයක් ලෙස, අපට මෙහි විස්තාරණ ප්රසාරණය භාවිතා කළ හැකිය str.format
:
>>> foo = 'FOO'
>>> bar = 'BAR'
>>> 'this is foo, {foo} and bar, {bar}'.format(**locals())
'this is foo, FOO and bar, BAR'
පයිතන් 3 හි අළුත්: මූල පද සමඟ පමණක් කාර්යයන් අර්ථ දැක්වීම
ඔබට යතුරුපදය තිබිය හැක්කේ තර්කයෙන් පසුව පමණි*args
- නිදසුනක් ලෙස, මෙහි, kwarg2
මූල පද තර්කයක් ලෙස ලබා දිය යුතුය - ස්ථානීය නොවේ:
def foo(arg, kwarg=None, *args, kwarg2=None, **kwargs):
return arg, kwarg, args, kwarg2, kwargs
භාවිතය:
>>> foo(1,2,3,4,5,kwarg2='kwarg2', bar='bar', baz='baz')
(1, 2, (3, 4, 5), 'kwarg2', {'bar': 'bar', 'baz': 'baz'})
එසේම, *
අසීමිත ස්ථානීය තර්ක සඳහා ඉඩ නොදී, මූලික වචන පමණක් තර්ක අනුගමනය කරන බව දැක්වීමට තනිවම භාවිතා කළ හැකිය.
def foo(arg, kwarg=None, *, kwarg2=None, **kwargs):
return arg, kwarg, kwarg2, kwargs
මෙන්න, kwarg2
නැවතත් පැහැදිලිව නම් කරන ලද, මූලික වචන තර්කයක් විය යුතුය:
>>> foo(1,2,kwarg2='kwarg2', foo='foo', bar='bar')
(1, 2, 'kwarg2', {'foo': 'foo', 'bar': 'bar'})
අපට නොමැති නිසා අපට තවදුරටත් අසීමිත ස්ථානීය තර්ක පිළිගැනීමට නොහැකිය *args*
:
>>> foo(1,2,3,4,5, kwarg2='kwarg2', foo='foo', bar='bar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes from 1 to 2 positional arguments
but 5 positional arguments (and 1 keyword-only argument) were given
නැවතත්, වඩාත් සරළව, මෙහිදී අපට kwarg
ලබා දිය යුත්තේ ස්ථානීයව නොව නමින් ය:
def bar(*, kwarg=None):
return kwarg
මෙම උදාහරණයේ දී, අපි kwarg
ස්ථානගතව සමත් වීමට උත්සාහ කළහොත් අපට දෝෂයක් ඇති බව අපට පෙනේ :
>>> bar('kwarg')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar() takes 0 positional arguments but 1 was given
අපි kwarg
පරාමිතිය මූල පද තර්කයක් ලෙස පැහැදිලිවම සම්මත කළ යුතුය .
>>> bar(kwarg='kwarg')
'kwarg'
පයිතන් 2 අනුකූල නිරූපණ
*args
(සාමාන්යයෙන් "තරු- **kwargs
ආග්ස්" යැයි කියනු ලැබේ ) සහ (තාරකා "ක්වාර්ග්ස්" යැයි පැවසීමෙන් ඇඟවිය හැකි නමුත් "ද්විත්ව තරු ක්වාර්ග්ස්" සමඟ පැහැදිළි වන්න) පයිතන්හි පොදු අංක *
සහ **
අංකනය භාවිතා කිරීම සඳහා වේ. මෙම විශේෂිත විචල්ය නම් අවශ්ය නොවේ (උදා: ඔබට භාවිතා කළ හැකි *foos
සහ **bars
), නමුත් සම්මුතියෙන් ඉවත්වීම ඔබේ සෙසු පයිතන් කේත රචකයන් කෝපයට පත් කරයි.
අපි සාමාන්යයෙන් මේවා භාවිතා කරන්නේ අපගේ ශ්රිතයට ලැබෙන්නේ කුමක් ද යන්න හෝ අප තර්ක කීයක් පසුකරන්නේ ද යන්න නොදන්නා විට ය, සමහර විට සෑම විචල්යයක්ම වෙන වෙනම නම් කිරීමේදී පවා අවුල් සහගත හා අතිරික්තයක් ඇති වේ (නමුත් මෙය සාමාන්යයෙන් පැහැදිලි වන අවස්ථාවකි ව්යංගයට වඩා හොඳයි).
උදාහරණ 1
පහත දැක්වෙන ශ්රිතය ඒවා භාවිතා කළ හැකි ආකාරය විස්තර කරන අතර හැසිරීම පෙන්නුම් කරයි. නම් කරන ලද b
තර්කය දෙවන ස්ථානීය තර්කය විසින් පෙර පරිභෝජනය කරනු ඇති බව සලකන්න :
def foo(a, b=10, *args, **kwargs):
'''
this function takes required argument a, not required keyword argument b
and any number of unknown positional arguments and keyword arguments after
'''
print('a is a required argument, and its value is {0}'.format(a))
print('b not required, its default value is 10, actual value: {0}'.format(b))
# we can inspect the unknown arguments we were passed:
# - args:
print('args is of type {0} and length {1}'.format(type(args), len(args)))
for arg in args:
print('unknown arg: {0}'.format(arg))
# - kwargs:
print('kwargs is of type {0} and length {1}'.format(type(kwargs),
len(kwargs)))
for kw, arg in kwargs.items():
print('unknown kwarg - kw: {0}, arg: {1}'.format(kw, arg))
# But we don't have to know anything about them
# to pass them to other functions.
print('Args or kwargs can be passed without knowing what they are.')
# max can take two or more positional args: max(a, b, c...)
print('e.g. max(a, b, *args) \n{0}'.format(
max(a, b, *args)))
kweg = 'dict({0})'.format( # named args same as unknown kwargs
', '.join('{k}={v}'.format(k=k, v=v)
for k, v in sorted(kwargs.items())))
print('e.g. dict(**kwargs) (same as {kweg}) returns: \n{0}'.format(
dict(**kwargs), kweg=kweg))
අප සමග, මෙම උත්සවය අත්සන සඳහා අන්තර්ජාලය උදව් පරීක්ෂා කර ගත හැක help(foo)
කිව හැකි,
foo(a, b=10, *args, **kwargs)
අපි මෙම ශ්රිතය සමඟ කතා කරමු foo(1, 2, 3, 4, e=5, f=6, g=7)
මුද්රණය කරන:
a is a required argument, and its value is 1
b not required, its default value is 10, actual value: 2
args is of type <type 'tuple'> and length 2
unknown arg: 3
unknown arg: 4
kwargs is of type <type 'dict'> and length 3
unknown kwarg - kw: e, arg: 5
unknown kwarg - kw: g, arg: 7
unknown kwarg - kw: f, arg: 6
Args or kwargs can be passed without knowing what they are.
e.g. max(a, b, *args)
4
e.g. dict(**kwargs) (same as dict(e=5, f=6, g=7)) returns:
{'e': 5, 'g': 7, 'f': 6}
උදාහරණ 2
අපට එය සපයන වෙනත් ශ්රිතයක් භාවිතා කර එය ඇමතිය හැකිය a
:
def bar(a):
b, c, d, e, f = 2, 3, 4, 5, 6
# dumping every local variable into foo as a keyword argument
# by expanding the locals dict:
foo(**locals())
bar(100)
මුද්රණ:
a is a required argument, and its value is 100
b not required, its default value is 10, actual value: 2
args is of type <type 'tuple'> and length 0
kwargs is of type <type 'dict'> and length 4
unknown kwarg - kw: c, arg: 3
unknown kwarg - kw: e, arg: 5
unknown kwarg - kw: d, arg: 4
unknown kwarg - kw: f, arg: 6
Args or kwargs can be passed without knowing what they are.
e.g. max(a, b, *args)
100
e.g. dict(**kwargs) (same as dict(c=3, d=4, e=5, f=6)) returns:
{'c': 3, 'e': 5, 'd': 4, 'f': 6}
උදාහරණ 3: සැරසිලි කරුවන්ගේ ප්රායෝගික භාවිතය
හරි, ඒ නිසා සමහර විට අපි තවමත් උපයෝගීතාව දැක නැත. එබැවින් අවකලනය කේතයට පෙර සහ / හෝ පසු අතිරික්ත කේත සමඟ ඔබට කාර්යයන් කිහිපයක් ඇතැයි සිතන්න. පහත දැක්වෙන නම් කරන ලද කාර්යයන් නිදර්ශන අරමුණු සඳහා ව්යාජ කේතයක් පමණි.
def foo(a, b, c, d=0, e=100):
# imagine this is much more code than a simple function call
preprocess()
differentiating_process_foo(a,b,c,d,e)
# imagine this is much more code than a simple function call
postprocess()
def bar(a, b, c=None, d=0, e=100, f=None):
preprocess()
differentiating_process_bar(a,b,c,d,e,f)
postprocess()
def baz(a, b, c, d, e, f):
... and so on
අපට මෙය වෙනස් ආකාරයකින් හැසිරවිය හැකි නමුත්, අපට අතිරික්තය සැරසිලි කරුවෙකු සමඟ නිස්සාරණය කළ හැකිය, එබැවින් අපගේ පහත උදාහරණයෙන් පෙන්නුම් කරන්නේ කෙසේද *args
සහ **kwargs
ඉතා ප්රයෝජනවත් වන්නේ කෙසේද යන්නයි :
def decorator(function):
'''function to wrap other functions with a pre- and postprocess'''
@functools.wraps(function) # applies module, name, and docstring to wrapper
def wrapper(*args, **kwargs):
# again, imagine this is complicated, but we only write it once!
preprocess()
function(*args, **kwargs)
postprocess()
return wrapper
අතිරික්තය අප විසින් සාධක කර ඇති පරිදි දැන් සෑම ඔතා ඇති ශ්රිතයක්ම වඩාත් සංක්ෂිප්තව ලිවිය හැකිය:
@decorator
def foo(a, b, c, d=0, e=100):
differentiating_process_foo(a,b,c,d,e)
@decorator
def bar(a, b, c=None, d=0, e=100, f=None):
differentiating_process_bar(a,b,c,d,e,f)
@decorator
def baz(a, b, c=None, d=0, e=100, f=None, g=None):
differentiating_process_baz(a,b,c,d,e,f, g)
@decorator
def quux(a, b, c=None, d=0, e=100, f=None, g=None, h=None):
differentiating_process_quux(a,b,c,d,e,f,g,h)
අපගේ කේතය සාධනය කිරීමෙන් *args
සහ **kwargs
අපට කිරීමට ඉඩ සලසන, අපි කේත රේඛා අඩු කර, කියවීමේ හැකියාව සහ නඩත්තු කිරීමේ හැකියාව වැඩි දියුණු කරමු, සහ අපගේ වැඩසටහනේ තර්කනය සඳහා තනි කැනොනිකල් ස්ථාන ඇත. මෙම ව්යුහයේ ඕනෑම කොටසක් වෙනස් කිරීමට අපට අවශ්ය නම්, එක් එක් වෙනසක් කිරීමට අපට එක් ස්ථානයක් තිබේ.