
在 Python 函数定义中,* 号主要有两种含义,取决于它出现的位置。
一、* 的两种用法
| 位置 | 含义 | 作用 |
|---|---|---|
| 在形参中 | 接收任意数量的位置参数 | def func(*args) |
| 在参数列表中间 | 分隔符 | 强制后面的参数必须用关键字传递 |
二、* 作为分隔符:强制关键字参数
在函数定义中,* 之后的所有参数,在调用时必须使用 参数名=值 的形式传递,不能只传值。
示例
def example(a, b, *, c, d):
print(a, b, c, d)
# 正确:c 和 d 用了关键字
example(1, 2, c=3, d=4)
# 错误:c 和 d 只传值,会被识别为位置参数
example(1, 2, 3, 4)
# TypeError: example() takes 2 positional arguments but 4 were given
三、代码示例
async def ainvoke(
self,
input: InputT | Command | None,
config: RunnableConfig | None = None,
*, # ← 分隔符
context: ContextT | None = None,
stream_mode: StreamMode = "values",
...
) -> dict[str, Any] | Any:
备注:
-
config之前的参数:可以用位置传,也可以用关键字传 -
context及之后的参数 :必须用关键字传#正确
await ainvoke(
input_data,
config=my_config,
context=my_context,
stream_mode="updates"
)#错误:context 后面的参数没带名字
await ainvoke(
input_data,
my_config,
my_context, # ← 没带参数名,会报错
"updates"
)
四、其他常见用法
1. *args:接收任意位置参数
def func(*args):
print(args)
func(1, 2, 3) # (1, 2, 3)
2. **kwargs:接收任意关键字参数
def func(**kwargs):
print(kwargs)
func(a=1, b=2) # {'a': 1, 'b': 2}
3. 三者结合
def func(a, b=1, *args, c=2, **kwargs):
pass
# a → 位置参数
# b=1 → 默认参数
# *args → 可变位置参数
# c=2 → 关键字参数(必须用关键字传)
# **kwargs → 可变关键字参数
五、总结
| 写法 | 含义 |
|---|---|
*args |
收集多余的位置参数,存为元组 |
**kwargs |
收集多余的关键字参数,存为字典 |
* 单独出现 |
分隔符,后面的参数必须用关键字传递 |
*, 后面紧跟参数 |
强制关键字参数(Keyword-Only Arguments) |