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

时间:2019-08-01 12:42:45

标签: python python-internals

inspect模块如何使它像参数一样没有默认值(尽管有),使它似乎,这样做的原因是什么(如果有的话)? / p>

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类的代码,我会看到:

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

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

所以问题是:

检查模块是如何做到这一点的? 有的理由吗?

1 个答案:

答案 0 :(得分:1)

显然,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?!