Python的inspect.Signature的签名似乎违反了python的签名规则

Python's inspect.Signature's signature seems to violate python's signatures rules

inspect 模块是如何使它 看起来 像一个参数没有默认值(虽然它有),这样做的原因是什么(如果在所有任何)?

inspect.Signature 的帮助显示 return_annotation 参数没有默认值:

>>> import inspect
>>> help(inspect.Signature)
(...)
class Signature(builtins.object)
 |  Signature(parameters=None, *, return_annotation, __validate_parameters__=True)
(...)

然而我们可以构造一个只有一个参数的签名:

>>> sig = inspect.Signature(None)
>>> # Nothing bad happens

这似乎违反了规则。所以查看 Signature class 的代码,我看到:

def __init__(self, parameters=None, *, return_annotation=_empty, __validate_parameters__=True)

好吧,return_annotation 毕竟有默认值(这就是 inspect.Signature(None) 起作用的原因)。

所以问题是:

inspect 模块是如何做到这一点的? 这样做有好处理由吗?

显然,help 在后台调用 inspect.signature(object),其中 object 是函数。这将 inspect.Signature.empty 默认参数视为 显示 根本没有默认值。

另一个例子:

>>> def thing(self, a=inspect.Signature.empty):
...     ...
... 
>>> help(thing)
Help on function thing in module __main__:

thing(self, a)  # Here it is!

您可以通过 运行 了解 help 函数在幕后的作用:

import trace
trace.Trace().runfunc(help, thing)

对我来说 (Python 3.6) 它显示了这个:

<snip>
pydoc.py(1357):             try:
pydoc.py(1358):                 signature = inspect.signature(object)
 --- modulename: inspect, funcname: signature
inspect.py(3002):     return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
 --- modulename: inspect, funcname: from_callable
inspect.py(2751):         return _signature_from_callable(obj, sigcls=cls,
<snip>
pydoc.py(1361):             if signature:
pydoc.py(1362):                 argspec = str(signature)

如果您在代码中复制它,您将得到:

>>> inspect.signature(thing)
<Signature (self, a)>
>>> str(_)
'(self, a)'  # huh?!