1. 四种常用的传参方式
def func(a=None, b=None, *args, **kwargs):
print(a, b, args, kwargs)
# 1. 位置参数(positional arguments):按 位置顺序 传参
func(1, 2)
# 1 2 () {}
# 2. 关键字参数(keyword arguments):按 关键字=值 传参
func(a = 1, b = 2)
# 1 2 () {}
# 3. 可变参数
func(1, 2, 3, 4)
# 1 2 (3, 4) {}
func(1, 2, 3, 4, {"c": 5, "d":6})
# 1 2 (3, 4, {'c': 5, 'd': 6}) {} 参数里的字典会作为位置参数传入
# func(a = 1, b = 2, 3, 4) # TODO: 关键字参数后不能跟位置参数
# 4. 可变关键字参数
func(1, b = 2, c = 3, d = 4)
# 1 2 () {'c': 3, 'd': 4}、
func(1, 2, 3, 4, **{"c": 5, "d":6})
# 1 2 (3, 4) {'c': 5, 'd': 6} 注意:** 可以解包字典,使之成为 c=5,d=6
func(1, b = 2, c = 3, d = 4, e = {"c": 5, "d":6})
# 1 2 () {'c': 3, 'd': 4, 'e': {'c': 5, 'd': 6}}
# 你发现了吗?
func(1, 2, 3, 4, {"c": 5, "d":6})
# 1 2 (3, 4, {'c': 5, 'd': 6}) {}
func(1, 2, 3, 4, **{"c": 5, "d":6})
# 1 2 (3, 4) {'c': 5, 'd': 6}
# 只要你传递了关键字参数,后面就不会继续接收位置参数了!
简单总结:
- 位置参数:位置参数是按位置顺序传参的。
- 关键字参数:函数定义时,如果有参数,则所有的形参名都是一个关键字,如果想通过关键字的方式传参,可以使用 关键字=值得方式传参,默认参数是在函数定义时就给参数传入了一个默认的参数值,如果函数调用时没有给这个参数传值,就使用默认值, 如果显式的传参了,就使用新传入的值代替默认值。
- 可变参数:可变参数是一个形参可以接受多个实参,用
*args
标志这是一个可变参数。可变参数的传入数是不决定的,通常由函数调用方决定。可变参数会将所有接受的值以元组的形式传入函数体内,如果可变参数没有接受到任何值,则传入一个空元组(,)。 - 可变关键字参数:可变关键字参数 用 双星号+参数名表示, 如:
** kwargs
,可变关键字参数接收零个或多个关键字参数,并以字典的形式传入函数体,关键字为此字典的key,关键字绑定的值为value。如果可变关键字没有接收到任何参数, 则传入函数体一个空字典{}。
2. 仅限关键字参数(Keyword-Only Arguments)
只能传入关键字参数。仅限关键字参数不可缺省(除非有默认值),且只能强制性通过关键字传参。
- 可变参数后面的关键字参数都是仅限关键字参数。
- 单星号"*"表示不接受任何可变参数,它可以作为普通参数的结束标志。
def func(*, a, b):
print(a, b)
func(a = 1, b = 2)
# 1 2
func(1, 2)
# TypeError: func() takes 0 positional arguments but 2 were given
def func(a, b, *args, c):
print(a, b, args, c)
func(1, 2, 3, 4, c = 5)
# 1 2 (3, 4) 5
3. 仅限位置参数(Positional-Only Arguments)
顾名思义,就是只能通过位置传参,不能使用关键字传参(a=1)。这是 Python3.8 新特性之一,在函数定义时,参数之间可指定一个斜杠(/),斜杠前的参数严格遵守仅位置参数的定义。
def func(a, b, /, *args, **kwargs):
print(a, b)
func(1, 2)
# 1 2
func(a=1, b=2)
# TypeError
如果 Python 版本是3.8以下,是不支持仅位置参数的语法的。提示:更新有风险。