Python 函数的参数系统非常灵活且强大。下面我将系统、清晰、完整地介绍 Python 函数的所有参数形式及其调用方式,并附上实用示例和注意事项。
一、函数参数的 5 种形式(定义时)
在 def
定义函数时,参数可以按以下顺序出现(顺序不能乱!):
def func(pos_only, /, # 1. 仅限位置参数(Python 3.8+)standard, # 2. 标准参数(位置或关键字)standard_with_default="default", # 3. 带默认值的标准参数*args, # 4. 可变位置参数(收集多余位置参数)kw_only, # 5. 仅限关键字参数(必须用关键字传)kw_only_with_default=True, # 6. 带默认值的仅限关键字参数**kwargs # 7. 可变关键字参数(收集多余关键字参数)
):pass
✅ 完整顺序口诀:
仅位置 → 普通参数 → 默认参数 →*args
→ 仅关键字 →**kwargs
下面我们逐一详解。
二、7 种参数形式详解
1. 仅限位置参数(Positional-Only Parameters)
语法:def f(a, b, /): ...
作用:这些参数只能通过位置传参,不能用关键字。
def div(x, y, /):return x / ydiv(10, 2) # ✅ OK
div(x=10, y=2) # ❌ TypeError! x 和 y 是仅位置参数
📌 引入版本:Python 3.8+
用途:保护内部 API,或模拟 C 函数行为(如len(obj)
不能写成len(obj=obj)
)。
2. 标准参数(Standard Parameters)
最常见的形式,既可用位置,也可用关键字传参。
def greet(name, greeting):print(f"{greeting}, {name}!")greet("Alice", "Hi") # 位置传参
greet(greeting="Hello", name="Bob") # 关键字传参
3. 带默认值的参数(Default Value Parameters)
在标准参数基础上提供默认值,调用时可省略。
def connect(host, port=80, ssl=True):print(f"Connect to {host}:{port}, SSL={ssl}")connect("example.com") # 使用默认 port=80, ssl=True
connect("api.com", port=443) # 覆盖 port
connect("db.com", ssl=False, port=5432) # 用关键字灵活传参
⚠️ 重要规则:
- 默认参数必须放在非默认参数之后
- 默认值在函数定义时计算一次(警惕可变默认值!)
4. 可变位置参数(*args
)
收集所有多余的位置参数,打包成元组。
def sum_all(a, *args):return a + sum(args)sum_all(1) # args = () → 1
sum_all(1, 2, 3, 4) # args = (2, 3, 4) → 10
5. 仅限关键字参数(Keyword-Only Parameters)
必须用关键字传参,不能靠位置。
def process_data(data, *, encoding='utf-8', errors='strict'):# * 之后的参数只能用关键字print(f"Encoding: {encoding}, Errors: {errors}")process_data("text", encoding="ascii") # ✅
process_data("text", "ascii") # ❌ TypeError!
💡 技巧:如果不需要
*args
,可以用单独的*
来开启仅关键字参数。
6. 带默认值的仅限关键字参数
和第 3 类类似,但只能用关键字传。
def save_file(path, *, backup=True, compress=False):print(f"Save {path}, backup={backup}, compress={compress}")save_file("data.txt", compress=True) # backup 用默认值
7. 可变关键字参数(**kwargs
)
收集所有多余的关键字参数,打包成字典。
def create_user(name, **kwargs):print(f"User: {name}")for k, v in kwargs.items():print(f" {k}: {v}")create_user("Alice", age=30, city="Beijing")
# 输出:
# User: Alice
# age: 30
# city: Beijing
三、函数调用的 3 种方式
在 调用函数时,你可以混合使用以下方式:
1. 位置参数(Positional Arguments)
按参数定义顺序传值。
func(1, 2, 3)
2. 关键字参数(Keyword Arguments)
通过 参数名=值
传参,顺序可变。
func(a=1, c=3, b=2)
3. 解包传参(Unpacking Arguments)
用 *
和 **
解包序列/字典传参。
args = (1, 2, 3)
kwargs = {"x": 10, "y": 20}func(*args, **kwargs) # 等价于 func(1, 2, 3, x=10, y=20)
四、调用时的规则(必须遵守!)
-
位置参数必须在关键字参数之前
func(1, 2, x=3) # ✅ func(x=3, 1, 2) # ❌ SyntaxError!
-
不能重复传同一个参数
def f(a): ... f(1, a=2) # ❌ TypeError: f() got multiple values for argument 'a'
-
不能传未定义的参数(除非有
**kwargs
)def f(a): ... f(a=1, b=2) # ❌ TypeError: unexpected keyword argument 'b'
五、完整示例:综合所有参数形式
def example(a, b, /, # 仅位置c, d=10, # 标准 + 默认*args, # 可变位置e, f=20, # 仅关键字 + 默认**kwargs # 可变关键字
):print(f"a={a}, b={b}") # 仅位置print(f"c={c}, d={d}") # 标准print(f"args={args}") # 多余位置参数print(f"e={e}, f={f}") # 仅关键字print(f"kwargs={kwargs}") # 多余关键字参数# 调用
example(1, 2, # a, b(必须位置)3, d=4, # c=3, d=45, 6, 7, # *args → (5, 6, 7)e=8, f=9, # e=8(必须关键字), f=9x=10, y=11 # **kwargs → {'x':10, 'y':11}
)
输出:
a=1, b=2
c=3, d=4
args=(5, 6, 7)
e=8, f=9
kwargs={'x': 10, 'y': 11}
六、最佳实践建议
场景 | 建议 |
---|---|
参数 ≤2 个 | 用位置参数即可 |
参数 ≥3 个或含布尔标志 | 优先用关键字参数调用(提高可读性) |
设计公共 API | 对可选配置使用默认参数 + 仅关键字参数 |
编写装饰器/代理函数 | 用 *args, **kwargs 保持通用性 |
避免可变默认值 | 用 None 代替 [] 或 {} |
# ✅ 安全的默认值写法
def add_item(item, lst=None):if lst is None:lst = []lst.append(item)return lst
七、总结图(参数定义顺序)
def func(pos_only, /,standard,standard_with_default="default",*args,kw_only,kw_only_with_default=True,**kwargs
):
记住这个顺序,你就掌握了 Python 函数参数的全部奥秘!