inspect.signature 与 类 究竟如何协同工作?

How exactly does inspect.signature work with classes?

inspect.signature 文档声明它支持 类 作为输入,但没有涉及任何细节:

Accepts a wide range of Python callables, from plain functions and classes to functools.partial() objects.

如果我调用 inspect.signature(MyClass),它的签名是什么 return? return MyClass.__init__ 的签名吗?还是MyClass.__new__?或者别的什么?

它几乎尽其所能地尝试一切。我认为细节可能是故意未记录的,因为它们很复杂并且可能会变得更多,因为新的 Python 版本添加了更多的东西来尝试。

例如,从 CPython 3.7.3 开始,code path 按顺序尝试以下操作:

  • 如果 metaclass 在 Python 中定义了自定义 __call__,它使用带有第一个参数的 metaclass __call__ 的签名已删除。
  • 否则,如果 class 具有 Python 中定义的 __new__ 方法,它会使用删除第一个参数的 __new__ 签名。
  • 否则,如果 class 具有 Python 中定义的 __init__ 方法,它会使用删除第一个参数的 __init__ 签名。
  • 否则,它遍历 MRO 寻找 __text_signature__。如果找到,它会解析 __text_signature__ 以获取签名信息。
  • 如果仍然没有找到任何东西,如果类型的 __init__object.__init__ 并且类型的 __new__object.__new__,它 returns object class 的签名。 (在这一点上有一个误导性的评论和一个可能涉及 metaclasses 的错误 - 评论说它将检查 type.__init__,但它并没有这样做。我认为 this commit可能这里弄错了。)
  • 如果它仍然没有找到任何东西,它会放弃并提出一个 ValueError 说它找不到任何东西。