编程后端开发者

在 Python 中,位置参数和关键字参数的工作机制是如何运作的?在定义函数和调用时,参数顺序有哪些细微差别,为什么需要仅位置参数和仅命名参数?

用 Hintsage AI 助手通过面试

答案。

在 Python 中,函数可以声明四种类型的参数:位置参数命名参数(keyword),仅位置参数(positional-only)和仅命名参数(keyword-only)。它们的区别会影响在调用函数时传递值的方式。

参数类型

  1. 位置参数(通常放在前面):值按照指定的顺序传递。
  2. 命名参数:通过名称明确指定。
  3. 仅位置参数:在符号 / 之前声明(Python 3.8+),无法按名称指定。
  4. 仅命名参数:在 * 之后声明,只能通过键指定。
# 所有类型的示例 def func(a, b, /, c, *, d, e): print(a, b, c, d, e) func(1, 2, 3, d=4, e=5) # OK # func(a=1, b=2, 3, d=4, e=5) # 错误:a,b - 仅位置参数

细节

  • 参数顺序:仅位置参数 / (位置或关键字) * 仅命名参数
  • 如果参数顺序错误,抛出 SyntaxErrorTypeError
  • *args 收集额外的定位参数;**kwargs 收集命名参数。

具有挑战性的问题。

函数声明有什么区别:

def f(a, b, c): ... def f(a, b, c=1): ... def f(a, b=1, c=2): ... def f(a=1, b=2, c=3): ...

这个真的可以用位置参数和关键字参数一起调用吗?

答案:

  • 对于函数 def f(a, b, c):,无法仅通过关键字参数调用,因为所有参数都可以按照位置或键传递,但所有参数都是必需的。
  • 如果参数不被定义为仅位置参数,则可以按名称指定。
  • 如果函数声明为 def f(a, b, /, c):,则 ab 只能以位置方式传递。

示例:

def f(a, b, c=10): print(a, b, c) f(1, 2) # OK,c=10 默认值 f(a=1, b=2, c=3) # OK # 而这是: def f(a, b, /, c=10): ... f(1, 2) # OK f(a=1, b=2, c=3) # 错误!a 和 b 仅位置传递

因为不熟悉该主题而导致的实际错误示例


故事

开发人员实现了一个函数,根据约定必须仅按名称接受参数:具有多个参数的日志记录,其中一些是可选的。但他们忘记声明 * — 用户意外按位置传递参数,导致错误的日志记录和难以追踪的错误。


故事

在使用 REST API 的项目中,由于隐式的参数顺序约定(使用 *args 并未限制命名参数),在引入新版本客户端后,请求开始失效 — 因为 args 被移位。通过引入显式的 * 和仅指定命名参数来解决了这个问题。


故事

在一个大型企业项目中,函数扩展了具有默认值的新参数,但由于错误调用位置参数,旧代码开始将值赋给其他参数,导致数据处理不正确。结果发现参数需要做成仅命名的。