python 函数参数的形式以及调用方式
Python 函数的参数系统非常灵活且强大。下面我将系统、清晰、完整地介绍 Python 函数的所有参数形式及其调用方式,并附上实用示例和注意事项。
一、函数参数的形式(定义时)
在 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 / y
div(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=4
5, 6, 7, # *args → (5, 6, 7)
e=8, f=9, # e=8(必须关键字), f=9
x=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 函数参数的全部奥秘!
浙公网安备 33010602011771号