一、基础概念:什么是关键字参数
Python 调用函数时传参分两种:位置参数、关键字参数
- 关键字参数:调用函数时,通过
形参名=值 的形式显式指定传给哪个参数,不受顺序限制
语法格式
# 定义函数
deffunc(a, b, c):
pass
# 关键字传参(顺序随意)
func(b=2, a=1, c=3)
二、关键字参数核心特性
1. 传参顺序不受限制
普通位置参数必须严格匹配定义顺序,关键字参数可任意调换:
defstudent(name, age, gender):
print(f"姓名:{name}, 年龄:{age}, 性别:{gender}")
# 纯位置参数(顺序固定)
student("小明", 18, "男")
# 纯关键字参数,顺序打乱完全没问题
student(gender="女", name="小红", age=17)
输出:
姓名:小明, 年龄:18, 性别:男
姓名:小红, 年龄:17, 性别:女
2. 位置参数必须写在关键字参数前面(硬性规则)
报错规则:调用函数时,位置参数不能出现在关键字参数后面
deftest(x, y):
pass
# 合法:位置在前,关键字在后
test(10, y=20)
# 非法:关键字在前,位置在后 → SyntaxError
test(x=10, 20)
3. 同一个参数不能重复传值
不能同时用位置+关键字给同一个形参赋值,会触发 TypeError
defadd(a, b):
return a + b
# 错误:a 既用位置传了1,又关键字传了10
add(1, a=10, b=2)
# TypeError: multiple values for argument 'a'
4. 关键字参数只能匹配函数已定义的形参
不能传入函数不存在的参数名,直接报错
defcalc(m, n):
pass
calc(m=5, k=6) # k不是函数参数,报错
# TypeError: calc() got an unexpected keyword argument 'k'
三、函数定义层面:默认参数(带关键字属性)
定义函数时给形参赋值,就是默认关键字参数,调用时可省略不传:
defuser_info(name, age=18, city="北京"):
print(name, age, city)
# 只传必填位置参数,默认参数自动生效
user_info("小李")
# 覆盖默认值,只修改city
user_info("小张", city="上海")
# 全部手动指定
user_info("小王", age=22, city="广州")
输出:
小李 18 北京
小张 18 上海
小王 22 广州
定义规则:带默认值的参数必须放在无默认值参数后面,否则语法报错
# 错误写法
deffunc(a=10, b):
pass
四、可变关键字参数 **kwargs(收集所有多余关键字参数)
1. 作用
捕获所有未匹配到普通形参的关键字参数,打包成字典存入 kwargs(约定变量名,可自定义) 语法:def 函数名(**kwargs):
示例1:基础收集
defprint_msg(**kwargs):
print(kwargs, type(kwargs))
for k, v in kwargs.items():
print(f"{k}: {v}")
# 传入任意多关键字参数
print_msg(name="莉莉", height=165, hobby="画画")
输出:
{'name': '莉莉', 'height': 165, 'hobby': '画画'} <class 'dict'>
name: 莉莉
height: 165
hobby: 画画
2. 普通参数 + **kwargs 混用
普通形参接收固定关键字,多余的全部进 kwargs
defgoods(name, price, **kwargs):
print(f"商品:{name}, 价格:{price}")
print("其他属性:", kwargs)
goods("手机", 3999, brand="华为", memory="256G")
输出:
商品:手机, 价格:3999
其他属性: {'brand': '华为', 'memory': '256G'}
3. 字典解包传参 **字典
调用函数时,用 **dict 将字典自动拆解为多个关键字参数:
defperson(name, age, sex):
print(name, age, sex)
info = {"name": "阿杰", "age": 20, "sex": "男"}
# 字典解包,等价于 person(name="阿杰", age=20, sex="男")
person(**info)
五、仅关键字参数(强制只能用关键字传参)
Python3 新增语法:仅关键字参数,必须用 参数=值 传参,禁止位置传参。 两种定义方式:
方式1:单星号 * 分隔
* 后面的所有形参,只能用关键字传入
defsend_email(to, *, subject, content):
print(f"收件:{to}, 标题:{subject}, 内容:{content}")
# 合法:*后面参数使用关键字
send_email("admin@qq.com", subject="通知", content="放假通知")
# 非法:给subject传位置参数,直接报错
send_email("admin@qq.com", "放假通知", content="xxx")
# TypeError: send_email() takes 1 positional argument but 3 were given
方式2:结合 *args
可变位置参数后的参数自动成为仅关键字参数
defcalc_sum(*nums, base):
return sum(nums) + base
# 必须关键字传base
print(calc_sum(1,2,3, base=10)) # 16
# calc_sum(1,2,3,10) 报错
六、参数完整顺序规范(最全优先级)
定义函数时,参数书写顺序必须严格遵守,否则语法错误:
标准模板:
deffull_func(a, b=10, *args, c, d=20, **kwargs):
pass
调用传参顺序规则:
合法调用示例:
full_func(1, 2, 3, 4, c=5, d=6, x=100, y=200)
full_func(10, d=30, *(5,6), c=15, **{"z": 99})
七、常见易错点总结
- 位置参数不能放在关键字参数之后
func(a=1, 2) # 语法错误
- 同一参数不能重复赋值
func(1, a=2) # 重复传a,报错
- 默认参数陷阱:不要用可变对象(列表/字典)当默认值
# 错误示范
defappend_item(x, arr=[]):
arr.append(x)
return arr
print(append_item(1)) # [1]
print(append_item(2)) # [1,2] 列表复用,不会重置
修正方案:defappend_item(x, arr=None):
if arr isNone:
arr = []
arr.append(x)
return arr
**kwargs 只能接收关键字,不能接收位置参数- 仅关键字参数必须显式写关键字,适合强制清晰传参(工具类函数常用)
八、实战应用场景
- 提高代码可读性:参数多时,关键字能一眼看懂每个值含义
# 可读性差
create_user(1, "张三", 18, True)
# 清晰易懂
create_user(id=1, name="张三", age=18, is_vip=True)
- 函数参数扩展:使用
**kwargs 兼容未来新增参数,无需修改函数调用 - 强制规范传参:仅关键字参数防止参数顺序传错引发bug