一、可变参数
- 可变参数
*args
允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple - 但
*args
不能处理带参数名的参数
def calc(*args):
result = 0
for arg in args:
result += arg
return result
print(calc(a=1, b=2, c=3))
会引发TypeError
错误,错误消息为
calc() got an unexpected keyword argument 'a'
二、关键字参数
- 关键字参数
**kw
(kw为参数名,可以自己取)允许你传入 0 个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict - 函数调用中必须以
参数名=参数值
传参 - 可以拓展函数的功能
例如person函数:
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
我们保证能接收到 name 和 age 这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
三、命名关键字参数
- 作用:限制关键字参数的名字,例如,只接收city和job作为关键字参数
- 函数调用中必须以
参数名=参数值
传参
两种命名方法:
- 命名关键字参数需要一个特殊分隔符 * ,* 后面的参数被视为命名关键字参数**
def person(name, age, *, city, job):
print(f'姓名:{name}, 年龄:{age},城市:{city}, 工作:{job}')
调用结果:
person('Jack', 24, city='Beijing', job='Engineer')
>>> 姓名:Jack, 年龄:24,城市:Beijing, 工作:Engineer
如果没有传入参数名:
person('Jack', 24, 'Beijing', 'Engineer')
报错:TypeError: person() takes 2 positional arguments but 4 were given
- 如果函数定义中已经有了一个可变参数*args,后面跟着的命名关键字参数就不再需要一个特殊分隔符 * 了:
def person(name, age, *args, city, job):
#city,job都是命名关键字参数
print(f'姓名:{name}, 年龄:{age},{args},城市:{city}, 工作:{job}')
调用:
person('Jack', 24, 'Beijing', 'Engineer')
报错:TypeError: person() missing 2 required keyword-only arguments: 'city' and 'job'
注:这里可变参数个数可以为0,但是命名关键字参数不能为0且必须以参数名=参数值写完
四、参数组合
- 函数定义时,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
- 函数引用时,不带参数名的参数(位置参数)必须出现在带参数名的参数 (关键字参数)之前,否则将会引发异常。
def person(name, age, *, city, job):
print(f'姓名:{name}, 年龄:{age},{args},城市:{city}, 工作:{job}')
person(city='Beijing', job='Engineer','Jack', 24)
报错:SyntaxError: positional argument follows keyword argument
小结:
- 函数引用时,可变参数
*args
,固定参数age,name
均属于 位置参数,仅能通过参数值传参 - 关键字参数
**tw
,命名关键字参数*,city,job
或者*args,city,job
均属于关键字参数,仅能通过参数名=参数值传参