*args
和**kwargs
是什么意思?def foo(x, y, *args):
pass
def bar(x, y, **kwargs):
pass
参见函数调用中的双星号和单星号有什么区别?了解有关参数的补充问题。
*args
和**kwargs
是什么意思?def foo(x, y, *args):
pass
def bar(x, y, **kwargs):
pass
参见函数调用中的双星号和单星号有什么区别?了解有关参数的补充问题。
*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
*args 是一个元组类型
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)
**kwd或**any是一个字典类型
def func(**any):
return type(any) # dict
def func(**any):
return any
func(width="10",height="20") # {width="10",height="20")
**
解包除了本主题中的答案外,还有一个细节没有在其他地方提到。这扩展了Brad Solomon的答案
使用**
进行解包时,在使用Python str.format
时也非常有用。
这与您可以使用Python f-strings做的事情有些类似,但需要声明一个字典来保存变量(f-string不需要字典)。
## init vars
ddvars = dict()
ddcalc = dict()
pass
ddvars['fname'] = 'Huomer'
ddvars['lname'] = 'Huimpson'
ddvars['motto'] = 'I love donuts!'
ddvars['age'] = 33
pass
ddcalc['ydiff'] = 5
ddcalc['ycalc'] = ddvars['age'] + ddcalc['ydiff']
pass
vdemo = []
## ********************
## single unpack supported in py 2.7
vdemo.append('''
Hello {fname} {lname}!
Today you are {age} years old!
We love your motto "{motto}" and we agree with you!
'''.format(**ddvars))
pass
## ********************
## multiple unpack supported in py 3.x
vdemo.append('''
Hello {fname} {lname}!
In {ydiff} years you will be {ycalc} years old!
'''.format(**ddvars,**ddcalc))
pass
## ********************
print(vdemo[-1])
*args
是一种特殊的参数,可以作为元组接受0个或多个位置参数。
**kwargs
是一种特殊的参数,可以作为字典接受0个或多个关键字参数。
*在Python中,有两种类型的参数:位置参数和关键字参数:
*args
:例如,*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)
当打印*args
时,会打印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'>
然而,*args
没有类型:
def test(*args):
print(type(*args)) # Here
test(1, 2, 3, 4)
输出(错误):
类型错误: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)
输出(错误):
SyntaxError:无效语法
而且,正常参数不能像下面这样放在*args
之后:
↓ ↓
def test(*args, num1, num2):
print(args, num1, num2)
test(1, 2, 3, 4)
输出(错误):
类型错误: 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
:例如,**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
时,会打印2个键:
def test(**kwargs):
print(*kwargs) # Here
test(name="John", age=27)
输出:
name age
而且,kwargs
是 字典 类型:
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)
输出(错误):
类型错误: 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)
输出(错误):
SyntaxError: 语法无效
*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}
def foo(x, y, *args):
pass
def bar(x, y, **kwargs):
pass
*args
据我所知,*args
是由逗号 ,
分隔的参数数组,因此如果您想要在上面使用 foo
,它将如下所示:
foo("x","y",1,2,3,4,5)
所以如果你运行
for a in args:
print(a)
它将按放置顺序打印参数为1、2、3...
虽然这很容易实现和使用,但参数的顺序在这里非常重要。因此,如果第一个参数应该是字符串,第二个参数是整数,如果调用者弄错了顺序,函数就会失败。
**kwargs
这些是关键字参数,它们是一组以键/值对
或字典
形式传递的命名参数,如果有多个,则用,
分隔。因此,对于bar
,您可以发送
bar("x", "y", name="vinod",address="bangalore",country="india")
并且可以在函数中单独读取它
Name = kwargs['name']
Address = kwargs['address']
kwargs
不需要枚举循环,参数的顺序也不重要。>>> def A(*tpl):
... print(tpl)
...
>>> A(6, 7, 8, 9, 0)
(6, 7, 8, 9, 0)
>>> def B(a, b, c, d, e):
... print(f"{a} {b} {c} {d} {e}")
...
>>> lst = [1,2,3,4,5]
>>>
>>> B(*lst)
1 2 3 4 5
>>> def C(**dic):
... print(dic)
...
>>> C(a=9, b=8, c=7, d=6, e=5)
{'a': 9, 'b': 8, 'c': 7, 'd': 6, 'e': 5}
>>> def D(v,w,x,y,z):
... print(f"{v} {w} {x} {y} {z}")
...
>>> dct = {'z':1, 'y':2, 'x':3, 'w':4, 'v':5}
>>>
>>> D(**dct)
5 4 3 2 1
def foo(param1, *param2):
是一种可以接受任意数量的值为*param2
的方法,def bar(param1, **param2):
是一种可以接受任意数量且带有键的值为*param2
的方法。param1
是一个简单参数。例如,在Java中实现varargs的语法如下:
accessModifier methodName(datatype… arg) {
// method body
}
*args
和**kwargs
只是一种将无限数量的字符输入函数的方法,例如:
def print_all(*args, **kwargs):
print(args) # print any number of arguments like: "print_all("foo", "bar")"
print(kwargs.get("to_print")) # print the value of the keyworded argument "to_print"
# example:
print_all("Hello", "World", to_print="!")
# will print:
"""
('Hello', 'World')
!
"""
*args
can be anything, like *something
, the same for **kwargs
, example: *keyworded_args
- Isaac Vinícius
def func(*args)
)。如果你想要了解在函数调用中func(*[1,2])
表示什么,请参见 这里。如果你想了解如何展开参数列表,请参见 这里。如果你想了解在 字面量 中 ([*[1, 2]]
)*
的含义,请参见 这里。 - Aran-Fey*
而不是**
)。 - Karl Knechtel