关于python:对于参数**(双星/星号)和*(单星号)做了什么?

关于python:对于参数**(双星/星号)和*(单星号)做了什么?

What does ** (double star/asterisk) and * (star/asterisk) do for parameters?

在以下方法定义中,***param2做了什么?

1
2
def foo(param1, *param2):
def bar(param1, **param2):

这是一个普通*args**kwargs成语让任意数的参数描述的功能和更多的在节定义函数在Python文档。

给你想要的所有功能参数*argsas a元组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
In [1]: def foo(*args):
   ...:     for a in args:
   ...:         print a
   ...:        
   ...:        

In [2]: foo(1)
1


In [4]: foo(1,2,3)
1
2
3

想给你所有的**kwargs除了这些参数对应的关键字到一个正式的参数作为一个字典。

1
2
3
4
5
6
7
8
9
In [5]: def bar(**kwargs):
   ...:     for a in kwargs:
   ...:         print a, kwargs[a]
   ...:        
   ...:        

In [6]: bar(name='one', age=27)
age 27
name one

这两个成语可以让混合参数与正常和一些变量的一组固定的参数:

1
2
def foo(kind, *args, **kwargs):
   pass

另一个用法的成语是*lunpack函数调用时参数列表。

1
2
3
4
5
6
7
8
9
In [9]: def foo(bar, lee):
   ...:     print bar, lee
   ...:    
   ...:    

In [10]: l = [1,2]

In [11]: foo(*l)
1 2

在Python中,它是可能的使用*l3的左侧向上扩展可迭代变量解包赋值给a list),虽然它不是在这个context of a元组:

1
2
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]

因此Python 3添加新的语义(指PEP 3102):

1
2
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
    pass

搜索功能只接受3定位和所有的参数后,*只能是作为关键字参数传递。


它是值得的,你可以使用一***当主叫功能为好。这是一个快捷方式,可以让你通过使用多参数的函数都是直接到一个列表或元组A / A的字典。例如,如果你有以下功能:

1
2
3
4
def foo(x,y,z):
    print("x=" + str(x))
    print("y=" + str(y))
    print("z=" + str(z))

你可以做这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> 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键参数函数的命名,也喜欢foo。否则它会掷TypeError:a

1
2
3
4
5
>>> 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'


单*意味着可以有任何数量的额外的定位参数。foo()可以foo(1,2,3,4,5)invoked样。在param2 Body of foo()是一个序列含2 5。

*《双均值可以有任何数量的额外的命名参数。bar()可以bar(1, a=2, b=3)invoked样。在酒吧(体)是一个含param2词典(A′B′2,3}

用下面的代码:

1
2
3
4
5
6
7
8
9
10
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
1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}

What does ** (double star) and * (star) do for parameters

它们允许定义函数接受并允许用户传递任意数量的参数、位置(*和关键字(**)。好的。定义函数

*args允许任意数量的可选位置参数(参数),这些参数将分配给名为args的元组。好的。

**kwargs允许任何数量的可选关键字参数(参数),这些参数将位于名为kwargs的dict中。好的。

您可以(并且应该)选择任何合适的名称,但是如果目的是让论点具有非特定的语义,那么argskwargs是标准名称。好的。扩展,传递任意数量的参数

您还可以使用*args**kwargs分别从列表(或任何可Itable)和dicts(或任何映射)传递参数。好的。

接收参数的函数不必知道它们正在被扩展。好的。

例如,python 2的xrange并不明确地期望*args,但因为它采用3个整数作为参数:好的。

1
2
3
>>> x = xrange(3) # create our *args - an iterable of 3 integers
>>> xrange(*x)    # expand here
xrange(0, 2, 2)

作为另一个例子,我们可以在str.format中使用dict扩展:好的。

1
2
3
4
>>> foo = 'FOO'
>>> bar = 'BAR'
>>> 'this is foo, {foo} and bar, {bar}'.format(**locals())
'this is foo, FOO and bar, BAR'

python 3中的新功能:使用仅关键字参数定义函数

*args后面只能有关键字参数-例如,这里,kwarg2必须作为关键字参数提供-而不是按位置提供:好的。

1
2
def foo(arg, kwarg=None, *args, kwarg2=None, **kwargs):
    return arg, kwarg, args, kwarg2, kwargs

用途:好的。

1
2
>>> foo(1,2,3,4,5,kwarg2='kwarg2', bar='bar', baz='baz')
(1, 2, (3, 4, 5), 'kwarg2', {'bar': 'bar', 'baz': 'baz'})

另外,*本身也可以用来指示后面只跟关键字参数,而不允许有无限的位置参数。好的。

1
2
def foo(arg, kwarg=None, *, kwarg2=None, **kwargs):
    return arg, kwarg, kwarg2, kwargs

这里,kwarg2再次必须是一个显式命名的关键字参数:好的。

1
2
>>> foo(1,2,kwarg2='kwarg2', foo='foo', bar='bar')
(1, 2, 'kwarg2', {'foo': 'foo', 'bar': 'bar'})

我们不能再接受无限制的位置参数,因为我们没有*args*:好的。

1
2
3
4
5
>>> 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以名称命名,而不是按位置命名:好的。

1
2
def bar(*, kwarg=None):
    return kwarg

在这个例子中,我们看到,如果我们试图按位置传递kwarg,我们会得到一个错误:好的。

1
2
3
4
>>> bar('kwarg')
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
TypeError: bar() takes 0 positional arguments but 1 was given

我们必须显式地将kwarg参数作为关键字参数传递。好的。

1
2
>>> bar(kwarg='kwarg')
'kwarg'

python 2兼容演示

*args**kwargs是python使用***符号的常用习惯用法。这些特定的变量名是不需要的(例如,您可以使用*foos**bars),但是偏离惯例很可能会激怒您的Python编码同事。好的。

我们通常在不知道函数将接收什么或传递多少参数时使用这些参数,有时甚至单独命名每个变量都会变得非常混乱和冗余(但在这种情况下,通常显式优于隐式)。好的。

例1好的。

下面的函数描述如何使用它们,并演示行为。注:命名的b参数将由前面的第二个位置参数使用:好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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)
{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:
{0}'
.format(
      dict(**kwargs), kweg=kweg))

我们可以通过help(foo)查看函数签名的在线帮助,它告诉我们好的。

1
foo(a, b=10, *args, **kwargs)

让我们用foo(1, 2, 3, 4, e=5, f=6, g=7)来调用这个函数好的。

哪些印刷品:好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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:好的。

1
2
3
4
5
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)印刷品:好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
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:装饰材料的实际应用好的。

好吧,也许我们还没有看到实用程序。所以假设您在区分代码之前和/或之后有几个具有冗余代码的函数。以下命名函数只是用于说明目的的伪代码。好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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是如何非常有用的:好的。

1
2
3
4
5
6
7
8
9
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

现在,每一个被包装的函数都可以写得更简洁,因为我们已经计算出了冗余度:好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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允许我们这样做),我们减少了代码行,提高了可读性和可维护性,并且在我们的程序中有唯一的逻辑规范位置。如果我们需要改变这个结构的任何部分,我们就有一个地方可以进行每一次改变。好的。好啊。


让我们首先了解什么是位置参数和关键字参数。下面是带有位置参数的函数定义示例。

1
2
3
4
5
6
7
8
9
10
def test(a,b,c):
     print(a)
     print(b)
     print(c)

test(1,2,3)
#output:
1
2
3

这是一个带有位置参数的函数定义。您也可以使用关键字/命名参数来调用它:

1
2
3
4
5
6
7
8
9
10
def test(a,b,c):
     print(a)
     print(b)
     print(c)

test(a=1,b=2,c=3)
#output:
1
2
3

现在让我们研究一个带有关键字参数的函数定义示例:

1
2
3
4
5
6
7
8
9
10
11
12
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
-------------------------

也可以使用位置参数调用此函数:

1
2
3
4
5
6
7
8
9
10
11
12
def test(a=0,b=0,c=0):
    print(a)
    print(b)
    print(c)
    print('-------------------------')

test(1,2,3)
# output :
1
2
3
---------------------------------

所以我们现在知道了带有位置参数和关键字参数的函数定义。

现在让我们研究一下‘*’操作符和‘*’操作符。

请注意,这些操作员可用于两个领域:

a)功能调用

b)功能定义

在函数调用中使用"*"运算符和"*"运算符。

让我们直接举一个例子,然后讨论它。

1
2
3
4
5
6
7
8
9
10
11
12
13
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.

所以记住

当函数调用中使用"*"或"*"运算符时-

"*"运算符将数据结构(如列表或元组)解包为函数定义所需的参数。

"**"运算符将字典解包为函数定义所需的参数。

现在让我们研究一下函数定义中使用的"*"运算符。例子:

1
2
3
4
5
6
7
8
9
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

在函数定义中,"*"运算符将接收到的参数打包成一个元组。

现在让我们看看函数定义中使用的"**"示例:

1
2
3
4
5
6
7
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

在函数定义中,"**"运算符将接收到的参数打包到字典中。

所以请记住:

在函数调用中,"*"将元组或列表的数据结构解包为位置参数或关键字参数,以便由函数定义接收。

在函数调用中,"**"将字典的数据结构解包为位置参数或关键字参数,以便由函数定义接收。

在函数定义中,"*"将位置参数打包为元组。

在函数定义中,**'将关键字参数打包到字典中。


***有特别使用在函数参数列表。*implies论点,这是一个名单,**implies论点是一个字典。这允许把任意数量的函数参数


对于你们这些通过例子学习的人!

  • *的目的是使您能够定义一个函数,该函数可以接受作为列表提供的任意数量的参数(例如f(*myList))。
  • **的目的是通过提供字典(例如f(**{'x' : 1, 'y' : 2})给您提供函数参数的能力。
  • 让我们通过定义一个函数来说明这一点,它采用两个正态变量xy,可以接受更多的参数作为myArgs,可以接受更多的参数作为myKW。稍后,我们将演示如何使用myArgDicty供电。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    def f(x, y, *myArgs, **myKW):
        print("# x      = {}".format(x))
        print("# y      = {}".format(y))
        print("# myArgs = {}".format(myArgs))
        print("# myKW   = {}".format(myKW))
        print("# ----------------------------------------------------------------------")

    # Define a list for demonstration purposes
    myList    = ["Left","Right","Up","Down"]
    # Define a dictionary for demonstration purposes
    myDict    = {"Wubba":"lubba","Dub":"dub
    <hr><P>从Python的文档:</p><blockquote>
      <p>
    If there are more positional arguments than there are formal parameter slots, a TypeError exception is raised, unless a formal parameter using the syntax"
    *identifier" is present; in this case, that formal parameter receives a tuple containing the excess positional arguments (or an empty tuple if there were no excess positional arguments).
    </p>
     
      <p>
    If any keyword argument does not correspond to a formal parameter name, a TypeError exception is raised, unless a formal parameter using the syntax"
    **identifier" is present; in this case, that formal parameter receives a dictionary containing the excess keyword arguments (using the keywords as keys and the argument values as corresponding values), or a (new) empty dictionary if there were no excess keyword arguments.
    </p>
    </blockquote><hr><P>虽然在python 3中已经扩展了star/splat操作符的使用,但我喜欢下表,因为它与这些操作符与函数的使用有关。splat运算符既可用于函数构造,也可用于函数调用:</P>[cc lang="
    python"]            In function construction         In function call
    =======================================================================
              |  def f(*args):                 |  def f(a, b):
    *args     |      for arg in args:          |      return a + b
              |          print(arg)            |  args = (1, 2)
              |  f(1, 2)                       |  f(*args)
    ----------|--------------------------------|---------------------------
              |  def f(a, b):                  |  def f(a, b):
    **kwargs  |      return a + b              |      return a + b
              |  def g(**kwargs):              |  kwargs = dict(a=1, b=2)
              |      return f(**kwargs)        |  f(**kwargs)
              |  g(a=1, b=2)                   |
    -----------------------------------------------------------------------

    这确实是为了总结洛林·霍克斯坦的答案,但我觉得这很有帮助。


    你可以在Python 3.5,所以使用本listdict,句法,和显示器(settuple,所以有时称为literals)。湖:额外的PEP 488 generalizations解包。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> (0, *range(1, 4), 5, *range(6, 8))
    (0, 1, 2, 3, 5, 6, 7)
    >>> [0, *range(1, 4), 5, *range(6, 8)]
    [0, 1, 2, 3, 5, 6, 7]
    >>> {0, *range(1, 4), 5, *range(6, 8)}
    {0, 1, 2, 3, 5, 6, 7}
    >>> d = {'one': 1, 'two': 2, 'three': 3}
    >>> e = {'six': 6, 'seven': 7}
    >>> {'zero': 0, **d, 'five': 5, **e}
    {'five': 5, 'seven': 7, 'two': 2, 'one': 1, 'three': 3, 'six': 6, 'zero': 0}

    它也允许一个多可迭代量unpacked A功能单一的呼叫。

    1
    2
    >>> range(*[1, 10], *[2])
    range(1, 10, 2)

    (感谢mgilson的PEP的链接。)


    我想举一个别人没有提到的例子

    *也可以打开发电机的包装

    python3文档中的示例

    1
    2
    3
    4
    x = [1, 2, 3]
    y = [4, 5, 6]

    unzip_x, unzip_y = zip(*zip(x, y))

    解压x将是[1,2,3],解压y将是[4,5,6]

    zip()接收多个iretable参数,并返回一个生成器。

    1
    zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))


    除了函数调用,*和* kwargs args是一流的。所以有hierarchies和避免__init__Python写的方法。相似使用Django框架的CAN湖泊类的代码。

    例如,

    1
    2
    3
    4
    5
    6
    7
    8
    def __init__(self, *args, **kwargs):
        for attribute_name, value in zip(self._expected_attributes, args):
            setattr(self, attribute_name, value)
            if kwargs.has_key(attribute_name):
                kwargs.pop(attribute_name)

        for attribute_name in kwargs.viewkeys():
            setattr(self, attribute_name, kwargs[attribute_name])

    一个CAN然后收藏指正

    1
    2
    3
    4
    5
    class RetailItem(Item):
        _expected_attributes = Item._expected_attributes + ['name', 'price', 'category', 'country_of_origin']

    class FoodItem(RetailItem):
        _expected_attributes = RetailItem._expected_attributes +  ['expiry_date']

    然后是instantiated AS的收藏指正

    1
    2
    3
    4
    5
    food_item = FoodItem(name = 'Jam',
                         price = 12.0,
                         category = 'Foods',
                         country_of_origin = 'US',
                         expiry_date = datetime.datetime.now())

    因此,一个新的属性这一收藏指正只理解这类的实例可以调用库收藏指正__init__到卸载位置属性的设置。这是做通过kwargs args和**。这样的代码主要用于kwargs is readable使用命名参数。例如,

    1
    2
    3
    4
    5
    6
    class ElectronicAccessories(RetailItem):
        _expected_attributes = RetailItem._expected_attributes +  ['specifications']
        # Depend on args and kwargs to populate the data as needed.
        def __init__(self, specifications = None, *args, **kwargs):
            self.specifications = specifications  # Rest of attributes will make sense to parent class.
            super(ElectronicAccessories, self).__init__(*args, **kwargs)

    可以instatiated AS

    1
    2
    3
    4
    5
    usb_key = ElectronicAccessories(name = 'Sandisk',
                                    price = '$6.00',
                                    category = 'Electronics',
                                    country_of_origin = 'CN',
                                    specifications = '4GB USB 2.0/USB 3.0')

    您的代码在这里


    * means receive variable arguments as list

    ** means receive variable arguments as dictionary

    Used like the following:

    1) single *

    1
    2
    3
    4
    5
    def foo(*args):
        for arg in args:
            print(arg)

    foo("two", 3)

    输出:

    1
    2
    two
    3

    2)现在是**

    1
    2
    3
    4
    5
    def bar(**kwargs):
        for key in kwargs:
            print(key, kwargs[key])

    bar(dic1="two", dic2=3)

    输出:

    1
    2
    dic1 two
    dic2 3

    这个例子可以帮助您同时记住Python中的*args**kwargs甚至super和继承。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class base(object):
        def __init__(self, base_param):
            self.base_param = base_param


    class child1(base): # inherited from base class
        def __init__(self, child_param, *args) # *args for non-keyword args
            self.child_param = child_param
            super(child1, self).__init__(*args) # call __init__ of the base class and initialize it with a NON-KEYWORD arg

    class child2(base):
        def __init__(self, child_param, **kwargs):
            self.child_param = child_param
            super(child2, self).__init__(**kwargs) # call __init__ of the base class and initialize it with a KEYWORD arg

    c1 = child1(1,0)
    c2 = child2(1,base_param=0)
    print c1.base_param # 0
    print c1.child_param # 1
    print c2.base_param # 0
    print c2.child_param # 1

    在函数中同时使用这两者的一个好例子是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    >>> def foo(*arg,**kwargs):
    ...     print arg
    ...     print kwargs
    >>>
    >>> a = (1, 2, 3)
    >>> b = {'aa': 11, 'bb': 22}
    >>>
    >>>
    >>> foo(*a,**b)
    (1, 2, 3)
    {'aa': 11, 'bb': 22}
    >>>
    >>>
    >>> foo(a,**b)
    ((1, 2, 3),)
    {'aa': 11, 'bb': 22}
    >>>
    >>>
    >>> foo(a,b)
    ((1, 2, 3), {'aa': 11, 'bb': 22})
    {}
    >>>
    >>>
    >>> foo(a,*b)
    ((1, 2, 3), 'aa', 'bb')
    {}

    DR

    它将传递给函数的参数分别打包到函数体内部的listdict中。当您这样定义函数签名时:

    1
    2
    def func(*args, **kwds):
        # do stuff

    它可以用任意数量的参数和关键字参数调用。非关键字参数打包到函数体内部名为args的列表中,关键字参数打包到函数体内部名为kwds的dict中。

    1
    func("this","is a list of","non-keyowrd","arguments", keyword="ligma", options=[1,2,3])

    现在在函数体中,当调用函数时,有两个局部变量:args,它是一个值为["this","is a list of","non-keyword","arguments"]的列表;kwds,它是一个值为dict的列表,它的值为{"keyword" :"ligma","options" : [1,2,3]}

    这也可以反向工作,即从主叫方。例如,如果您有一个函数定义为:

    1
    2
    def f(a, b, c, d=1, e=10):
        # do stuff

    您可以通过解包调用范围中的iterables或映射来调用它:

    1
    2
    3
    4
    5
    iterable = [1, 20, 500]
    mapping = {"d" : 100,"e": 3}
    f(*iterable, **mapping)
    # That call is equivalent to
    f(1, 20, 500, d=100, e=3)


    *args**kwargs:允许您向函数传递可变数量的参数。

    *args用于向函数发送非关键字变长参数列表:

    1
    2
    3
    4
    5
    6
    7
    def args(normal_arg, *argv):
        print ("normal argument:",normal_arg)

        for arg in argv:
            print("Argument in list of arguments from *argv:", arg)

    args('animals','fish','duck','bird')

    将产生:

    1
    2
    3
    4
    normal argument: animals
    Argument in list of arguments from *argv: fish
    Argument in list of arguments from *argv: duck
    Argument in list of arguments from *argv: bird

    **kwargs*

    **kwargs允许您将参数的关键字可变长度传递给函数。如果要在函数中处理命名参数,应该使用**kwargs

    1
    2
    3
    4
    5
    6
    def who(**kwargs):
        if kwargs is not None:
            for key, value in kwargs.items():
                print ("Your %s is %s." %(key,value))

    who (name="Nikola", last_name="Tesla", birthday ="7.10.1856", birthplace ="Croatia")

    将产生:

    1
    2
    3
    4
    Your name is Nikola.
    Your last_name is Tesla.
    Your birthday is 7.10.1856.
    Your birthplace is Croatia.

    • def foo(param1, *param2):是一种可以接受*param2任意数量值的方法。
    • def bar(param1, **param2):是一种使用*param2的键可以接受任意数量的值的方法。
    • param1是一个简单的参数。

    例如,在Java中实现VARARGS的语法如下:

    1
    2
    3
    accessModifier methodName(datatype… arg) {
        // method body
    }

    推荐阅读

      linux命令简写自定义?

      linux命令简写自定义?,系统,状态,命令,代码,工具,发行,标准,软件,文件,别名,L

      linux下cd命令参数?

      linux下cd命令参数?,工作,命令,系统,一致,名称,目录,用户,缩写,意思,参数,lin

      linux各种命令的参数?

      linux各种命令的参数?,网络,信息,工作,地址,系统,情况,服务,命令,软件,数据,l

      linux命令行参数长度?

      linux命令行参数长度?,系统,信息,实时,工具,工作,名称,环境,百分比,标准,情

      linux添加命令参数?

      linux添加命令参数?,系统,管理,工作,基础,命令,情况,网络,工具,代码,环境,别

      linux用户自定义命令?

      linux用户自定义命令?,系统,时间,标准,软件,项目,电脑,服务,工具,基本知识,

      linux命令参数长度?

      linux命令参数长度?,工作,系统,信息,基础,网络,环境,情况,管理,长度,命令,Lin

      linux安装参数命令?

      linux安装参数命令?,工作,系统,软件,地址,命令,中心,在线,地方,位置,信息,Lin

      linux自定义快捷命令?

      linux自定义快捷命令?,系统,首次,位置,时间,文件,命令,链接,快捷键,终端,桌

      linux的命令的参数?

      linux的命令的参数?,网络,工作,系统,信息,情况,服务,命令,状态,数据,标准,Lin

      linux命令传入参数?

      linux命令传入参数?,系统,地址,工作,命令,信息,名称,代码,名字,服务,管理,如

      linux命令行参数的和?

      linux命令行参数的和?,系统,地址,管理,命令,基础,数字,网络,情况,下降,信息,

      linux带参数的命令?

      linux带参数的命令?,网络,地址,工作,信息,系统,情况,状态,服务,目录,命令,Lin

      linux内核命令行参数?

      linux内核命令行参数?,系统,地址,工作,信息,命令,设备,第一,时间,服务,情况,l

      linux自定义全局命令?

      linux自定义全局命令?,环境,系统,命令,别名,新增,信息,地方,文件,定义,用户,

      linux命令参数过长?

      linux命令参数过长?,系统,管理,工作,命令,基础,环境,位置,档案,名称,信息,新

      linux不带参数的命令?

      linux不带参数的命令?,系统,单位,信息,管理,名称,标准,命令,进程,音乐,终端,l

      linux命令参数总结?

      linux命令参数总结?,系统,管理,信息,命令,密码,单位,位置,文件,基础,名称,Lin

      rlinux命令行参数?

      rlinux命令行参数?,地址,工作,系统,信息,命令,管理,目录,标准,文件,控制台,li

      linux命令参数位置?

      linux命令参数位置?,工作,系统,命令,信息,标准,状态,位置,地址,文件,简介,lin