Python:斜杠在help()输出中意味着什么?

Jos*_*hua 119 python introspection python-3.x

在关闭括号之前/,Python 3.4的help输出意味着什么range

>>> help(range)
Help on class range in module builtins:

class range(object)
 |  range(stop) -> range object
 |  range(start, stop[, step]) -> range object
 |  
 |  Return a virtual sequence of numbers from start to stop by step.
 |  
 |  Methods defined here:
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __eq__(self, value, /)
 |      Return self==value.

                                        ...
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 148

它表示仅位置参数的结束,您不能将参数用作关键字参数.此类参数只能在C API中指定.

它意味着key参数__contains__只能通过position(range(5).__contains__(3))传递,而不是作为关键字参数(range(5).__contains__(key=3))传递,你可以使用pure-python函数中的位置参数.

另请参阅Argument Clinic文档:

要在Argument Clinic中将所有参数标记为仅位置,请/在最后一个参数后自行添加一行,缩进与参数行相同.

语法也已定义为可能的未来包含在Python中,请参阅PEP 457 - 仅限位置参数的语法.目前,PEP充当对语法的保留,因此没有实际的计划来实现它.

  • 一个有趣的副作用是,仅位置参数的名称不会与“**kwargs”冲突,这对于函数式编程或装饰函数很有用,其中装饰器参数名称可能与装饰函数参数发生冲突。 (10认同)
  • @hugovdberg:我有一段时间感到困惑,但你正在谈论 `delay_call2()` 签名中的 `func` **参数**,其中第 50 行的调用之所以有效,是因为 `func` (关键字) *参数*不会与“func”参数冲突。是的,在您必须使用“*args”并从中解压分配给“func”参数的参数之前,这是语法的一个令人愉快的副作用。一般来说:函数签名中的名称是参数,调用表达式中传入的值是参数。使讨论调用两侧使用的语法变得更容易。 (3认同)
  • @MarcosPereira:提出的问题是*什么*:*help() 输出中的斜杠意味着什么?*。 (2认同)

nav*_*nam 17

正斜杠 (/) 表示它之前的所有参数都是位置参数。在接受PEP 570后,python 3.8 中添加了仅位置参数功能。最初,这个符号是在PEP 457 - Notation for Notation For Positional-Only Parameters 中定义的

Foraward 斜杠 (/) 之前的函数定义中的参数只是位置参数,斜杠 (/) 后面的参数可以是任何类型的语法。其中参数仅根据调用函数时的位置映射到仅位置参数。通过关键字(名称)传递仅位置参数无效。

让我们以下面的例子

def foo(a, b, / , x, y):
   print("positional ", a, b)
   print("positional or keyword", x, y)
Run Code Online (Sandbox Code Playgroud)

在上面的函数定义中,参数 a 和 b 仅是位置参数,而 x 或 y 可以是位置参数或关键字。

以下函数调用有效

foo(40, 20, 99, 39)
foo(40, 3.14, "hello", y="world")
foo(1.45, 3.14, x="hello", y="world")
Run Code Online (Sandbox Code Playgroud)

但是,以下函数调用无效,这会引发异常 TypeError,因为 a、b 不是作为位置参数传递而是作为关键字传递

foo(a=1.45, b=3.14, x=1, y=4)
Run Code Online (Sandbox Code Playgroud)

类型错误:foo() 得到了一些作为关键字参数传递的仅位置参数:'a, b'

python 中的许多内置函数只接受位置参数,其中通过关键字传递参数没有意义。例如内置函数len只接受一个 positional(only) 参数,其中调用 len as len(obj="hello world") 会降低可读性,请检查 help(len)。

>>> help(len)
Help on built-in function len in module builtins:

len(obj, /)
    Return the number of items in a container.
Run Code Online (Sandbox Code Playgroud)

仅位置参数使底层 c/库函数易于维护。它允许将来更改仅位置参数的参数名称,而不会破坏使用 API 的客户端代码

最后但并非最不重要的一点是,仅位置参数允许我们在可变长度关键字参数中使用它们的名称。检查以下示例

>>> def f(a, b, /, **kwargs):
...     print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3)         # a and b are used in two ways
10 20 {'a': 1, 'b': 2, 'c': 3}
Run Code Online (Sandbox Code Playgroud)

仅位置参数更好在 Python 中的函数参数类型中解释:仅位置参数

仅位置参数语法正式添加到python3.8。查看python3.8 的新功能 - 仅位置参数

PEP 相关:PEP 570 -- Python Positional-Only 参数


pro*_*sti 11

我自己问了这个问题。:)发现这/是Guido最初在这里提出的。

替代方案:使用'/'怎么样?它与“ *”相反,后者表示“关键字参数”,而“ /”不是新字符。

然后他的提议获胜

h 如果是这样,我的“ /”建议将获胜:

 def foo(pos_only, /, pos_or_kw, *, kw_only): ...
Run Code Online (Sandbox Code Playgroud)

我认为涉及此的非常相关的文件是PEP 570。回顾部分看起来不错。

概括

用例将确定在函数定义中使用哪些参数:

 def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
Run Code Online (Sandbox Code Playgroud)

作为指导:

仅在名称无关紧要或名称没有含义并且仅会以相同顺序传递少数几个参数的情况下才使用仅位置。仅当名称具有含义且通过使用名称显式使函数定义更易于理解时,才应使用仅关键字。


如果函数以 /

def foo(p1, p2, /)
Run Code Online (Sandbox Code Playgroud)

这意味着所有功能参数都是位置性的。

  • 选择`/`标记,因为“它是`*`的逆运算”表明Python有点疯狂。这是一种联觉。 (19认同)
  • `def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2)` 无疑是记住两者的最佳和简洁的方法......两者是什么?不是参数,不是关键字,不是运算符……啊,它也在 PEP 中……两个标记。至少如果您还记得在引入标记之前标准参数是“pos_or_kwd”。 (3认同)