Python *args, **kwargs 的用法和用处

时间:2020-12-04 21:23:49

在 * 上看到了对 *args和**kargs 比较好的解释,分享一下,顺便补充一些例子

def func(required_arg, *args, **kwargs):
# required_arg is a positional-only parameter.
print(required_arg)

# args is a tuple of positional arguments,
# because the parameter name has * prepended.
if args: # If args is not empty.
print(args)

# kwargs is a dictionary of keyword arguments,
# because the parameter name has ** prepended.
if kwargs: # If kwargs is not empty.
print(kwargs)

>>> func()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() takes at least 1 argument (0 given)

>>> func("required argument")
required argument

>>> func("required argument", 1, 2, '3')
required argument
(1, 2, '3')

>>> func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")
required argument
(1, 2, '3')
{'keyword2': 'foo', 'keyword1': 4}

>>> func("required argument", 1, keyword1=4, 2, '3',keyword2="foo")
File "<ipython-input-24-92187cb5dc7e>", line 1
func("required argument", 1, keyword1=4, 2, '3',keyword2="foo")
^
SyntaxError: positional argument follows keyword argument
# 说明参数的顺序不能乱


>>> func(required_arg="required argument", 1, 2, '3', keyword1=4 ,keyword2="foo")
File "<ipython-input-30-de2b4309d741>", line 1
func(required_arg="required argument", 1, 2, '3', keyword1=4 ,keyword2="foo")
^
SyntaxError: positional argument follows keyword argument
# 说明第一个参数只能是positional arg, 不能指定名称

>>> func(1, 2, '3', required_arg="required argument", keyword1=4 ,keyword2="foo")
Traceback (most recent call last):

File "<ipython-input-28-12444e9d53db>", line 1, in <module>
func(1, 2, '3', required_arg="required argument", keyword1=4 ,keyword2="foo")

TypeError: func() got multiple values for argument 'required_arg'
# 如果把已经定义的参数放在后面,就会出现一个参数有两个值的情况

下面举个例子说明 *args, **kwargs 的用处

class Foo(object):
def __init__(self, value1, value2):
# do something with the values
print value1, value2

class MyFoo(Foo):
def __init__(self, *args, **kwargs):
# do something else, don't care about the args
print 'myfoo'
super(MyFoo, self).__init__(*args, **kwargs)

当一个类需要继承另一个类的时候,例如MyFoo需要继承Foo,假设你不知道Foo有哪些参数,而只关注子类MyFoo的扩展(另一种情况是将来Foo可能会有变化),这时你就可以利用*args, **kwargs 来代表Foo的所有参数,传入到MyFoo

星号 *, 涉及到解包, unpacking, 这又是另一个话题了