*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
当前回答
这个示例将帮助您立即记住Python中的*args、**kwargs甚至super和继承。
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
其他回答
*args和**kwargs:允许您向函数传递可变数量的参数。
*args:用于向函数发送非关键字可变长度参数列表:
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')
将产生:
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。
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")
将产生:
Your name is Nikola.
Your last_name is Tesla.
Your birthday is 7.10.1856.
Your birthplace is Croatia.
*args和**kwargs是一种常见的习惯用法,允许任意数量的函数参数,如Python文档中关于定义函数的更多章节所述。
*参数将以元组的形式提供所有函数参数:
def foo(*args):
for a in args:
print(a)
foo(1)
# 1
foo(1,2,3)
# 1
# 2
# 3
**kwargs会给你所有关键字参数,但与作为字典的形式参数相对应的参数除外。
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
*l习惯用法的另一个用法是在调用函数时打开参数列表。
def foo(bar, lee):
print(bar, lee)
l = [1,2]
foo(*l)
# 1 2
在Python 3中,可以在赋值的左侧使用*l(Extended Iterable Unpacking),尽管它在上下文中给出了一个列表而不是元组:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Python 3还添加了新的语义(参见PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
例如,以下命令在python 3中有效,但在python 2中无效:
>>> x = [1, 2]
>>> [*x]
[1, 2]
>>> [*x, 3, 4]
[1, 2, 3, 4]
>>> x = {1:1, 2:2}
>>> x
{1: 1, 2: 2}
>>> {**x, 3:3, 4:4}
{1: 1, 2: 2, 3: 3, 4: 4}
这样的函数只接受3个位置参数,*之后的所有参数只能作为关键字参数传递。
注:
语义上用于传递关键字参数的Python dict是任意排序的。然而,在Python 3.6中,关键字参数保证记住插入顺序。“**kwargs中元素的顺序现在对应于关键字参数传递给函数的顺序。”-Python3.6中的新功能事实上,CPython 3.6中的所有dict都将记住插入顺序作为实现细节,这在Python 3.7中成为标准。
TL;博士
它将传递给函数的参数分别打包到函数体中的list和dict中。当您这样定义函数签名时:
def func(*args, **kwds):
# do stuff
它可以用任意数量的参数和关键字参数调用。非关键字参数被打包到函数体内名为args的列表中,关键字参数被包装到函数体内称为kwds的dict中。
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是一个具有值为{“keyword”:“ligma”,“options”:[1,2]}的dict
这也反过来起作用,即从呼叫者一侧起。例如,如果函数定义为:
def f(a, b, c, d=1, e=10):
# do stuff
您可以通过打开调用范围中的可迭代项或映射来调用它:
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)
从Python文档中:
如果位置参数多于形式参数槽,则会引发TypeError异常,除非存在使用语法“*identifier”的形式参数;在这种情况下,该形参接收包含多余位置参数的元组(如果没有多余位置参数,则为空元组)。如果任何关键字参数与正式参数名称不对应,则会引发TypeError异常,除非存在使用语法“**标识符”的正式参数;在这种情况下,该形参接收包含多余关键字参数的字典(使用关键字作为关键字,将参数值作为对应值),如果没有多余关键字参数,则接收(新的)空字典。
*和**在函数参数列表中有特殊用法*表示参数是列表,**表示参数是一本字典。这允许函数接受任意数量的论据