背景
在学习python时发现方法调用和方法定义会经常发现有带星号的标记,为了弄明白是怎么使用的。特此做个笔记。
一、参数符号对比速查表
符号类 | 使用场景 | 作用描述 | 示例 |
---|---|---|---|
无符号 | 函数定义/调用 | 普通位置参数或关键字参数 | .def func(a, b) |
* | 函数定义 | 收集多余位置参数为元组 | .def func(*args) |
* | 函数调用 | 解包可迭代对象为位置参数 | .func(*[1,2]) |
** | 函数定义 | 收集多余关键字参数为字典 | def func(**kwargs) |
** | 函数调用 | 解包字典为关键字参数 | func(**{‘x’:1}) |
单独* | 参数分隔 | 强制后续参数必须用关键字指定 | def func(a, *, b) |
二、核心区别详解
1. 无符号参数(基础参数)
# 位置参数示例
def add(a, b):
return a + b
add(3, 5) # ✅ 正确:位置传参
add(b=5, a=3) # ✅ 正确:关键字传参
2. 单星号(*)参数
定义时使用(收集位置参数)
def log(*values):
print(type(values)) # <class 'tuple'>
print(values)
log(1, 'A', True) # 输出: (1, 'A', True)
调用时使用(解包可迭代对象)
def plot(x, y):
print(f"绘制点({x},{y})")
points = [5, 8]
plot(*points) # 等效于 plot(5, 8)
3. 双星号(**)参数
定义时使用(收集关键字参数)
def user_info(**details):
print(type(details)) # <class 'dict'>
print(details)
user_info(name='Alice', age=25) # 输出: {'name': 'Alice', 'age': 25}
调用时使用(解包字典)
def create_profile(name, age):
print(f"{name} | {age}岁")
data = {'name': 'Bob', 'age': 30}
create_profile(**data) # 等效于 create_profile(name='Bob', age=30)
4. 强制关键字参数(单独*)
def register(username, *, email, phone):
print(f"注册用户: {username}, 邮箱: {email}, 电话: {phone}")
register("wyz", email="wyz@example.com", phone="13800138000") # ✅ 正确
register("bob456", "bob@test.com", "12345678911") # ❌ 报错:email和phone必须用关键字参数
三、混合使用案例
def complex_example(a, b=0, *args, c, d=10, **kwargs):
print(f"""
固定参数: a={a}, b={b}
可变位置参数: args={args}
强制关键字参数: c={c}, d={d}
可变关键字参数: kwargs={kwargs}
""")
complex_example(1, 2, 3, 4, c=5, e=20, f=30)
# 输出:
# 固定参数: a=1, b=2
# 可变位置参数: args=(3, 4)
# 强制关键字参数: c=5, d=10
# 可变关键字参数: kwargs={'e': 20, 'f': 30}