包含:位置参数、关键字参数、默认参数、可变位置参数*args、可变关键字参数**kwargs、仅限位置参数/、仅限关键字参数*,附带易错坑点、练习题。
一、参数分类总览
- 位置参数(positional arguments):按顺序传参
- 关键字参数(keyword arguments):key=value 指定传参
- 默认参数(default parameters):定义时赋值,不传则使用默认值
- **可变位置参数
*args**:接收任意多个位置实参,打包成元组 tuple - **可变关键字参数
**kwargs**:接收任意多个关键字实参,打包成字典 dict - **仅限位置形参
/**:/ 左边只能用位置传参,不能关键字传参 - **仅限关键字形参
***:* 右边只能用关键字传参,不能位置传参
1. 位置参数
规则:实参顺序必须和形参一一对应,数量一致
deffunc(a, b, c):
print(f"a={a}, b={b}, c={c}")
# 正确:位置传参
func(10, 20, 30)
# 错误:参数数量不匹配
# func(1,2)
# func(1,2,3,4)
2. 关键字参数
规则:不需要顺序,使用 形参名=值;不能位置传参后再乱序关键字
deffunc(a, b, c):
print(f"a={a}, b={b}, c={c}")
func(a=1, b=2, c=3)
func(c=9, a=7, b=8) # 顺序随意
# ✅ 混合使用:位置参数必须放在关键字参数前面
func(5, b=6, c=7)
# ❌ 报错:关键字参数不能出现在位置参数前面
# func(a=1, 2, 3)
3. 默认参数(高频坑!)
基础用法
deffunc(a, b=100):
print(a + b)
func(10) # b 使用默认 100 → 110
func(10, 20) # 传入实参覆盖默认值 → 30
⚠️ 经典大坑:默认参数不要使用可变对象(list/dict)
# 错误示范!不要这样写
defbad_func(item, lst=[]):
lst.append(item)
print(lst)
bad_func(1) # [1]
bad_func(2) # [1,2] 意外累加!列表只会创建一次
# ✅ 正确写法:默认值设为 None,函数内部初始化可变对象
defgood_func(item, lst=None):
if lst isNone:
lst = []
lst.append(item)
print(lst)
good_func(1) # [1]
good_func(2) # [2]
4. 可变位置参数 *args
收集多余位置实参,得到元组
deffunc(a, *args):
print(f"a = {a}")
print(f"args = {args}, type={type(args)}")
func(1)
func(10, 20, 30, 40)
# 元组解包传入 *
nums = (1, 2, 3)
func(0, *nums)
输出:
a = 1
args = (), type=<class 'tuple'>
a = 10
args = (20, 30, 40), type=<class 'tuple'>
a = 0
args = (1, 2, 3), type=<class 'tuple'>
5. 可变关键字参数 **kwargs
收集多余关键字实参,得到字典
deffunc(a, **kwargs):
print(f"a={a}")
print(f"kwargs={kwargs}, type={type(kwargs)}")
func(10, name="张三", age=18)
# 字典解包 **
info = {"sex": "男", "height": 180}
func(50, **info)
6. *args + **kwargs 组合(万能参数)
接收任意参数,通用封装常用
defall_param_func(*args, **kwargs):
print("位置参数元组:", args)
print("关键字参数字典:", kwargs)
all_param_func(1, 2, 3)
all_param_func(x=100, y=200)
all_param_func(10, 20, name="test", num=66)
7. 参数完整顺序规范(必须遵守!)
标准顺序位置形参 → 默认参数 → *args → 仅限关键字参数 → **kwargs
# 合法顺序
defdemo(a, b=10, *args, c, d=99, **kwargs):
print(a, b, args, c, d, kwargs)
# c 必须使用关键字传参
demo(1, 2, 3, 4, c=5, d=6, name="demo")
# ❌ 非法顺序示例
# def demo(*args, a, b=10):
# def demo(**kwargs, *args):
8. 仅限位置参数 /(Python3.8+)
/ 左侧形参只允许位置传参,不能关键字传参
deffunc(a, b, /, c):
print(a, b, c)
func(1, 2, 3) # ok
func(1, 2, c=30) # ok
# ❌ 报错 a、b 不能关键字传参
# func(a=1, b=2, c=3)
9. 仅限关键字参数 *
* 右侧形参必须使用关键字传参
deffunc(a, *, b, c):
print(a, b, c)
func(10, b=20, c=30)
# ❌ func(10, 20, 30) 报错
10. 终极混合完整版示例(综合所有参数)
deffull_demo(a, b=5, /, arg1, *args, kw1, kw2=100, **kwargs):
print(f"a={a}, b={b}")
print(f"arg1={arg1}, args={args}")
print(f"kw1={kw1}, kw2={kw2}")
print(f"kwargs={kwargs}\n")
full_demo(1, 2, 10, 20, 30, kw1=88, kw2=99, city="西安")
full_demo(6, 7, 9, kw1=77, hobby="coding")
📝 课后练习题(带参考答案)
练习1
编写函数 calc_sum,接收任意多个数字,返回总和
# 参考答案
defcalc_sum(*args):
return sum(args)
print(calc_sum(1,2,3))
print(calc_sum(10,20,30,40))
练习2
编写函数 user_info,必填参数 name,可选参数 age(默认None),接收任意多关键字信息,打印所有信息
defuser_info(name, age=None, **kwargs):
print(f"姓名:{name}, 年龄:{age}")
print("其他信息:", kwargs)
user_info("小明", 19, sex="男", grade="大一")
user_info("小红")
练习3 判断下面代码会不会报错,说出原因
deftest(x, *args, y, **kwargs):
pass
# test(1,2,3,4)
答案:报错。y是仅限关键字参数,调用时没有传入y
练习4 改错:修复下面默认参数bug
defadd_num(n, res=[]):
res.append(n)
return res
print(add_num(1))
print(add_num(2))
参考答案defadd_num(n, res=None):
if res isNone:
res = []
res.append(n)
return res
print(add_num(1))
print(add_num(2))
拓展知识点:实参解包
deffunc(a,b,c):
print(a,b,c)
lst = [11,22,33]
func(*lst) # 列表解包 → 位置参数
dic = {"a":100, "b":200, "c":300}
func(**dic) # 字典解包 → 关键字参数