*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
当前回答
我想举一个别人没有提到的例子
*也可以打开发电机
Python3文档中的示例
x = [1, 2, 3]
y = [4, 5, 6]
unzip_x, unzip_y = zip(*zip(x, y))
unzip x将为(1,2,3),unzip y将为(4,5,6)
zip()接收多个iretable参数,并返回一个生成器。
zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))
其他回答
*args是一个特殊的参数,可以将0个或多个(位置)参数作为元组。**kwargs是一个特殊的参数,可以将0个或多个(关键字)参数作为字典。
*在Python中,有两种参数位置参数和关键字参数:
*参数:
例如,*args可以采用0个或多个参数作为元组,如下所示:
↓
def test(*args):
print(args)
test() # Here
test(1, 2, 3, 4) # Here
test((1, 2, 3, 4)) # Here
test(*(1, 2, 3, 4)) # Here
输出:
()
(1, 2, 3, 4)
((1, 2, 3, 4),)
(1, 2, 3, 4)
并且,当打印*参数时,将打印4个数字,不带括号和逗号:
def test(*args):
print(*args) # Here
test(1, 2, 3, 4)
输出:
1 2 3 4
并且,args具有元组类型:
def test(*args):
print(type(args)) # Here
test(1, 2, 3, 4)
输出:
<class 'tuple'>
但是,*参数没有类型:
def test(*args):
print(type(*args)) # Here
test(1, 2, 3, 4)
输出(错误):
TypeError:type()需要1或3个参数
并且,正常参数可以放在*args之前,如下所示:
↓ ↓
def test(num1, num2, *args):
print(num1, num2, args)
test(1, 2, 3, 4)
输出:
1 2 (3, 4)
但是,**kwargs不能放在*args之前,如下所示:
↓
def test(**kwargs, *args):
print(kwargs, args)
test(num1=1, num2=2, 3, 4)
输出(错误):
语法错误:无效语法
而且,正常参数不能放在*args之后,如下所示:
↓ ↓
def test(*args, num1, num2):
print(args, num1, num2)
test(1, 2, 3, 4)
输出(错误):
TypeError:test()缺少2个必需的仅关键字参数:“num1”和“num2”
但是,如果正常参数具有默认值,则可以将它们放在*args之后,如下所示:
↓ ↓
def test(*args, num1=100, num2=None):
print(args, num1, num2)
test(1, 2, num1=3, num2=4)
输出:
(1, 2) 3 4
此外,**kwargs可以放在*args之后,如下所示:
↓
def test(*args, **kwargs):
print(args, kwargs)
test(1, 2, num1=3, num2=4)
输出:
(1, 2) {'num1': 3, 'num2': 4}
**克瓦格斯:
例如,**kwargs可以使用0个或多个参数作为字典,如下所示:
↓
def test(**kwargs):
print(kwargs)
test() # Here
test(name="John", age=27) # Here
test(**{"name": "John", "age": 27}) # Here
输出:
{}
{'name': 'John', 'age': 27}
{'name': 'John', 'age': 27}
并且,当打印*kwargs时,将打印两个键:
def test(**kwargs):
print(*kwargs) # Here
test(name="John", age=27)
输出:
name age
并且,kwargs具有dict类型:
def test(**kwargs):
print(type(kwargs)) # Here
test(name="John", age=27)
输出:
<class 'dict'>
但是,*kwargs和**kwargs没有类型:
def test(**kwargs):
print(type(*kwargs)) # Here
test(name="John", age=27)
def test(**kwargs):
print(type(**kwargs)) # Here
test(name="John", age=27)
输出(错误):
TypeError:type()需要1或3个参数
并且,正常参数可以放在**kwargs之前,如下所示:
↓ ↓
def test(num1, num2, **kwargs):
print(num1, num2, kwargs)
test(1, 2, name="John", age=27)
输出:
1 2 {'name': 'John', 'age': 27}
此外,*args可以放在**kwargs之前,如下所示:
↓
def test(*args, **kwargs):
print(args, kwargs)
test(1, 2, name="John", age=27)
输出:
(1, 2) {'name': 'John', 'age': 27}
并且,正常参数和*args不能放在**kwargs之后,如下所示:
↓ ↓
def test(**kwargs, num1, num2):
print(kwargs, num1, num2)
test(name="John", age=27, 1, 2)
↓
def test(**kwargs, *args):
print(kwargs, args)
test(name="John", age=27, 1, 2)
输出(错误):
语法错误:无效语法
对于*args和**kwargs:
实际上,您可以为*args和**kwargs使用其他名称,如下所示*args和**kwargs通常使用:
↓ ↓
def test(*banana, **orange):
print(banana, orange)
test(1, 2, num1=3, num2=4)
输出:
(1, 2) {'num1': 3, 'num2': 4}
这个示例将帮助您立即记住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
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)
*和**在函数参数列表中有特殊用法*表示参数是列表,**表示参数是一本字典。这允许函数接受任意数量的论据
我想举一个别人没有提到的例子
*也可以打开发电机
Python3文档中的示例
x = [1, 2, 3]
y = [4, 5, 6]
unzip_x, unzip_y = zip(*zip(x, y))
unzip x将为(1,2,3),unzip y将为(4,5,6)
zip()接收多个iretable参数,并返回一个生成器。
zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))