*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
当前回答
*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中成为标准。
其他回答
我想举一个别人没有提到的例子
*也可以打开发电机
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和**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中成为标准。
还值得注意的是,在调用函数时也可以使用*和**。这是一个快捷方式,允许您直接使用列表/元组或字典将多个参数传递给函数。例如,如果您具有以下功能:
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中的键必须与函数foo的参数完全相同。否则将抛出TypeError:
>>> 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'
给定一个有3项作为参数的函数
sum = lambda x, y, z: x + y + z
sum(1,2,3) # sum 3 items
sum([1,2,3]) # error, needs 3 items, not 1 list
x = [1,2,3][0]
y = [1,2,3][1]
z = [1,2,3][2]
sum(x,y,z) # ok
sum(*[1,2,3]) # ok, 1 list becomes 3 items
想象一下这个玩具有一个三角形、一个圆形和一个长方形的袋子。那个包不太合身。你需要打开袋子,取出这3件物品,现在它们就可以了。Python*运算符执行此解包过程。
根据尼克的回答。。。
def foo(param1, *param2):
print(param1)
print(param2)
def bar(param1, **param2):
print(param1)
print(param2)
def three_params(param1, *param2, **param3):
print(param1)
print(param2)
print(param3)
foo(1, 2, 3, 4, 5)
print("\n")
bar(1, a=2, b=3)
print("\n")
three_params(1, 2, 3, 4, s=5)
输出:
1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
1
(2, 3, 4)
{'s': 5}
基本上,任何数量的位置参数都可以使用*args,任何命名参数(或kwargs又名关键字参数)都可以使用**kwargs。