Python 函数参数中的 * 和 ** 是什么意思?

*args 收集多余的位置参数为元组,**kwargs 收集关键字参数为字典;调用时用 * 解包列表、用 ** 解包字典。本文详解星号参数的用法与常见坑。

最佳实践
Python 函数参数中的 * 和 ** 是什么意思?封面

一句话解释:在函数定义中,*args 表示"接收任意数量的位置参数,打包成元组",**kwargs 表示"接收任意数量的关键字参数,打包成字典";在函数调用中,*列表 把序列解包成位置参数,**字典 把字典解包成关键字参数。

定义时:收集参数

def demo(arg1, *args, **kwargs):
    print(arg1)    # 必传参数
    print(args)    # 其余位置参数组成的元组
    print(kwargs)  # 关键字参数组成的字典

demo(1, 2, 3, 4, keyword1=5, keyword2=6)
# 1
# (2, 3, 4)
# {'keyword1': 5, 'keyword2': 6}

argskwargs 只是约定俗成的名字,写成 *values**options 也完全合法,星号本身才是语法。

调用时:解包参数

def add(a, b):
    return a + b

nums = [1, 2]
opts = {'b': 10}

print(add(*nums))          # 3,等价于 add(1, 2)
print(add(5, **opts))      # 15,等价于 add(5, b=10)

解包写法在包装已有函数、转发参数时特别好用:

def logged_call(func, *args, **kwargs):
    logging.info("调用 %s, args=%s, kwargs=%s", func.__name__, args, kwargs)
    return func(*args, **kwargs)

参数顺序规则

定义函数时参数顺序必须是:普通参数 → *args → 仅限关键字参数 → **kwargs

def f(a, b=1, *args, kw_only, **kwargs): ...

kw_only 这种位于 *args 之后的参数,调用时只能用关键字传入,常用于强制调用方写清语义。

观测云对照

用 kwargs 透传日志上下文。 给业务封装统一日志函数时,用 **kwargs 接收结构化字段再合并进 JSON 日志,DataKit 采集后经 Pipeline 解析成可检索字段,排查问题更顺手。

常见问题(FAQ)

Q:* 能单独出现不带变量名吗?
A:可以,def f(a, *, b) 表示 b 是仅限关键字参数,必须写成 f(1, b=2)

Q:调用时位置解包和关键字解包能混用吗?
A:可以,*args 在前、**kwargs 在后:func(*list, **dict)

Q:*args 收集的元组能修改吗?
A:元组不可变,但可以在函数内转成 list 处理,不影响外部调用方。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台