inspect.signature如何与类一起使用?

7
inspect.signature 文档中说明它支持类作为输入,但并未详细说明。其接受广泛的 Python 可调用对象,包括普通函数、类以及 functools.partial() 对象。如果我调用 inspect.signature(MyClass),它将返回什么签名?它会返回 MyClass.__init__ 的签名还是 MyClass.__new__ 的签名?或者其他的东西?
1个回答

13

它尽可能地尝试了所有合理的方法。我认为这些细节可能是有意不记录的,因为它们很复杂,并且随着新的Python版本添加更多内容,可能会变得更加复杂。

例如,在CPython 3.7.3中,代码路径按顺序尝试以下内容:

  • 如果元类在Python中定义了自定义__call__,则使用元类__call__的签名,第一个参数已删除。
  • 否则,如果类在Python中定义了__new__方法,则使用__new__签名,第一个参数已删除。
  • 否则,如果类在Python中定义了__init__方法,则使用__init__签名,第一个参数已删除。
  • 否则,它遍历MRO查找__text_signature__。 如果找到一个,它会解析__text_signature__以获取签名信息。
  • 如果仍然没有找到任何东西,且该类型的__init__object.__init__并且该类型的__new__object.__new__,则返回object类的签名。(在这一点上有一个误导性的注释和可能涉及元类的错误-该注释说它要检查type.__init__,但它并没有这样做。我认为这个提交可能在这里犯了一个错误。)
  • 如果仍然没有找到任何内容,则放弃并引发一个ValueError,表示无法找到任何内容。

  • 2
    哈哈,即使使用@staticmethod修饰,它实际上仍会截断元类的__call__的第一个参数。不错的微妙错误。 - Aran-Fey

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接