python - Qu'est-ce que ** (double star/asterisk) et * (star/asterisk) font pour les paramètres

Mots clés : pythonsyntaxparameter-passingvariadic-functionsargument-unpackingpython

meilleur 5 Réponses python - Qu'est-ce que ** (double star/asterisk) et * (star/asterisk) font pour les paramètres

vote vote

91

def foo(*args):     for a in args:         print(a)          foo(1) # 1  foo(1,2,3) # 1 # 2 # 3 
def bar(**kwargs):     for a in kwargs:         print(a, kwargs[a])    bar(name='one', age=27) # name one # age 27 
def foo(kind, *args, **kwargs):    pass 
def foo(a, b, c):     print(a, b, c)  obj = {'b':10, 'c':'lee'}  foo(100,**obj) # 100 10 lee 
def foo(bar, lee):     print(bar, lee)  l = [1,2]  foo(*l) # 1 2 
first, *rest = [1,2,3,4] first, *l, last = [1,2,3,4] 
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):     pass 
vote vote

85

def foo(x,y,z):     print("x=" + str(x))     print("y=" + str(y))     print("z=" + str(z)) 
>>> mylist = [1,2,3] >>> foo(*mylist) x=1 y=2 z=3  >>> mydict = {'x':1,'y':2,'z':3} >>> foo(**mydict) x=1 y=2 z=3  >>> mytuple = (1, 2, 3) >>> foo(*mytuple) x=1 y=2 z=3 
>>> mydict = {'x':1,'y':2,'z':3,'badnews':9} >>> foo(**mydict) Traceback (most recent call last):   File "<stdin>", line 1, in <module> TypeError: foo() got an unexpected keyword argument 'badnews' 
vote vote

77

def foo(param1, *param2):     print(param1)     print(param2)  def bar(param1, **param2):     print(param1)     print(param2)  foo(1,2,3,4,5) bar(1,a=2,b=3) 
1 (2, 3, 4, 5) 1 {'a': 2, 'b': 3} 
vote vote

62

>>> x = xrange(3) # create our *args - an iterable of 3 integers >>> xrange(*x)    # expand here xrange(0, 2, 2) 
>>> foo = 'FOO' >>> bar = 'BAR' >>> 'this is foo, {foo} and bar, {bar}'.format(**locals()) 'this is foo, FOO and bar, BAR' 
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 
>>> foo(1,2,kwarg2='kwarg2', foo='foo', bar='bar') (1, 2, 'kwarg2', {'foo': 'foo', 'bar': 'bar'}) 
>>> 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 
def bar(*, kwarg=None):      return kwarg 
>>> bar('kwarg') Traceback (most recent call last):   File "<stdin>", line 1, in <module> TypeError: bar() takes 0 positional arguments but 1 was given 
>>> bar(kwarg='kwarg') 'kwarg' 
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)) 
foo(a, b=10, *args, **kwargs) 
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} 
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())  
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} 
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 
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) 
vote vote

60

def test(a,b,c):      print(a)      print(b)      print(c)  test(1,2,3) #output: 1 2 3 
def test(a,b,c):      print(a)      print(b)      print(c)  test(a=1,b=2,c=3) #output: 1 2 3 
def test(a=0,b=0,c=0):      print(a)      print(b)      print(c)      print('-------------------------')  test(a=1,b=2,c=3) #output : 1 2 3 ------------------------- 
def test(a=0,b=0,c=0):     print(a)     print(b)     print(c)     print('-------------------------')  test(1,2,3) # output : 1 2 3 --------------------------------- 
def sum(a,b):  #receive args from function calls as sum(1,2) or sum(a=1,b=2)     print(a+b)  my_tuple = (1,2) my_list = [1,2] my_dict = {'a':1,'b':2}  # Let us unpack data structure of list or tuple or dict into arguments with help of '*' operator sum(*my_tuple)   # becomes same as sum(1,2) after unpacking my_tuple with '*' sum(*my_list)    # becomes same as sum(1,2) after unpacking my_list with  '*' sum(**my_dict)   # becomes same as sum(a=1,b=2) after unpacking by '**'   # output is 3 in all three calls to sum function. 
def sum(*args): #pack the received positional args into data structure of tuple. after applying '*' - def sum((1,2,3,4))     sum = 0     for a in args:         sum+=a     print(sum)  sum(1,2,3,4)  #positional args sent to function sum #output: 10 
def sum(**args): #pack keyword args into datastructure of dict after applying '**' - def sum({a:1,b:2,c:3,d:4})     sum=0     for k,v in args.items():         sum+=v     print(sum)  sum(a=1,b=2,c=3,d=4) #positional args sent to function sum 

Questions similaires