什么是__signature__和__text_signature__在Python 3.4中使用

Ant*_*ala 11 python signature python-internals python-3.4

如果dir()在CPython 3.4上对某些内置可调用对象(类构造函数,方法等)进行处理,则会发现其中许多通常具有一个特殊属性__text_signature__,例如:

>>> object.__text_signature__
'()'
>>> int.__text_signature__
>>> # was None
Run Code Online (Sandbox Code Playgroud)

但是,此文档不存在.此外,谷歌搜索属性名称表明还有另一个可能的特殊属性__signature__,但我没有找到任何内置函数.

我知道它们与函数参数签名有关,但除此之外,它们的值表示什么以及它们的用途是什么?

Mar*_*ers 12

这些属性用于启用C代码中定义的Python对象的内省.的C-API参数诊所提供数据,以协助inspect建立时模块Signature的对象.之前不支持对C-API函数进行自省.

请参阅有关如何使用该值的内部inspect._signature_fromstr()函数__text_signature__.

目前,该__text_signature__属性是从C-API中对象的内部docstring集填充的; 进行简单的文本搜索objectname(...)\n--\n\n,其中\n--\n\n典型的是Attribute Clinic生成的文档字符串.如果您想查找一些示例,请查看type对象槽.或者您可以查看audioop模块源以查看Argument Clinic如何用于定义签名; 该参数诊所脚本正在建设时产生的文档字符串(在附带的那些运行audioop.c.h文件).

__signature__属性,如果存在的话,将是一个inspect.Signature()对象; 而不是提供文本版本,C-API可以提供完全解析的Signature实例.

  • 不过,您的答案中有一个严重错误,C-API 称为 Argument Clinic,是对同名 Monty Python 草图的引用;) (3认同)
  • @Antti:*我曾经告诉过您*。 (2认同)
  • 开头仍然写着“属性诊所”:D (2认同)
  • @Antti:*不,不是*。抱歉,这是5分钟的争论还是整整半个小时的争论? (2认同)
  • 哦...只有五分钟。 (2认同)

Ray*_*ger 7

快速总结

这两个属性由inspect.signature()函数用于检索有关函数或方法调用签名的元数据。

实际应用

手动指定这些属性之一的一个用例是为使用*args.

在此示例中,randrange()方法用于*args接受可变数量的输入。但是,我们希望提供给help()和工具提示的签名显示每个参数的含义,以便它匹配相应的range()函数。

import random

class Random(random.Random):
    
    def randrange(self, /, *args):
        'Choose a random value from range(start[, stop[, step]]).'
        return self.choice(range(*args))

    randrange.__text_signature__ = '($self, start, stop=None, step=1, /)'
Run Code Online (Sandbox Code Playgroud)

__text_signature__属性通知签名对象的创建:

>>> inspect.signature(Random.randrange)
<Signature (self, start, stop=None, step=1, /)>
Run Code Online (Sandbox Code Playgroud)

这使得help()输出更有用:

>>> help(Random.randrange)
Help on function randrange in module __main__:

randrange(self, start, stop=None, step=1, /)
    Choose a random value from range(start[, stop[, step]]).
Run Code Online (Sandbox Code Playgroud)