Python 编程 - 星号下划线参数释义

在 Python 3 中,函数参数中的 *_ 主要有两种完全不同的理解方式,具体取决于它出现在函数定义中还是函数调用/解包中。

场景一:在函数定义中(def func(*_):)—— 收集并忽略多余的位置参数

这是最常见的用法。这里的 * 是“可变位置参数”语法(类似 *args),而 _ 是变量名(下划线)。

  • 作用:将所有传入的多余的位置参数打包成一个元组(Tuple),赋值给变量 _
  • 潜台词_ 是 Python 中约定俗成的“无关紧要变量”(Don't care variable)。合起来 *_ 的意思就是:“我接受任意数量的位置参数,但我根本不在乎它们是什么,直接丢掉”。

示例代码:

def log_message(msg, *_):
    # 只打印第一个参数,后面的全部忽略
    print(f"Log: {msg}")

log_message("Error", "details", 123, "extra")
# 输出: Log: Error
# 后面的 "details", 123, "extra" 被 *_ 吃掉并丢弃了

常见使用场景:

  • 继承/重写父类方法:当子类不需要父类的某些参数,但又必须保持签名兼容时。
  • 回调函数:某些库会传递很多参数给回调函数,但你只需要前两个。
  • 解耦:明确告诉阅读代码的人:“这些参数我用不到,别管它们”。

场景二:在函数定义中(def func(arg, *, _=None):)—— 强制关键字参数

这里的 * 单独出现,后面跟着参数 _。在 Python 3 中,* 单独使用时表示分隔符,它强制其后面的所有参数必须以关键字参数(key=value)的形式传递。

  • 作用_ 变成了一个普通的可选参数,但必须写成 _=xxx 才能传值。
  • 潜台词:API 设计者不想让你按位置乱传值,必须显式指明参数名。

示例代码:

def register_user(name, *, _=None):
    print(f"Name: {name}, Extra: {_}")

# 正确调用(必须写 _=)
register_user("Alice", _="admin")

# 错误调用(会报错,因为位置参数太多了)
# register_user("Alice", "admin")  
# TypeError: register_user() takes 1 positional argument but 2 were given

场景三:在函数调用中(func(*_))—— 解包序列

如果 _ 是一个列表或元组,在调用函数时写 func(*_),这是序列解包操作。

  • 作用:将列表/元组 _ 中的元素拆开,作为位置参数依次传入函数。
  • 注意:这里的 *_ 不是定义参数,而是传入参数

示例代码:

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

params = [1, 2, 3]
result = add(*params)  # 等同于 add(1, 2, 3)
print(result)  # 输出 6

总结速查表

写法位置 语法含义 实际效果
def func(*_) 可变位置参数 + 丢弃变量 收集所有多余位置参数并忽略,常用于忽略无用入参。
def func(_, *, _)def func(*, _) 强制关键字参数分隔符 后面的 _ 必须用关键字传值(_=xxx)。
func(*_) (调用时) 序列解包(星号表达式) _ 里的元素拆开当作多个参数传进去。

如果你是在看某个开源框架(如 PyTorch、Django)的源码,看到的 *_,99% 是“场景一”,表示“我接受参数但我选择忽略它们”,目的是为了兼容接口或占位。

posted @ 2026-07-05 17:16  箫笛  阅读(4)  评论(0)    收藏  举报