*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
当前回答
单*表示可以有任意数量的额外位置参数。foo()可以像foo(1,2,3,4,5)一样调用。在foo()的主体中,param2是一个包含2-5的序列。
双**表示可以有任意数量的额外命名参数。bar()可以像bar(1,a=2,b=3)一样调用。在bar()的主体中,param2是一个字典,其中包含{‘a‘:2,‘b‘:3}
使用以下代码:
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}
其他回答
这个示例将帮助您立即记住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是一种常见的习惯用法,允许任意数量的函数参数,如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中成为标准。
*args(或*any)表示每个参数
def any_param(*param):
pass
any_param(1)
any_param(1,1)
any_param(1,1,1)
any_param(1,...)
注意:不能将参数传递给*args
def any_param(*param):
pass
any_param() # will work correct
*参数的类型为元组
def any_param(*param):
return type(param)
any_param(1) #tuple
any_param() # tuple
用于访问不使用的元素*
def any(*param):
param[0] # correct
def any(*param):
*param[0] # incorrect
**千瓦时
**kwd或**任何这是字典类型
def func(**any):
return type(any) # dict
def func(**any):
return any
func(width="10",height="20") # {width="10",height="20")
给定一个有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*运算符执行此解包过程。
我想举一个别人没有提到的例子
*也可以打开发电机
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))