Python 3.4中的__signature__和__text_signature__有什么作用?

24

如果在CPython 3.4上对一些内置可调用对象(类构造函数、方法等)执行dir(),则会发现它们中的许多常常具有一个称为__text_signature__的特殊属性,例如:

>>> object.__text_signature__
'()'
>>> int.__text_signature__
>>> # was None

然而,这方面的文档不存在。此外,在搜索属性名称时,还建议存在另一个可能的特殊属性__signature__,尽管我没有找到任何具备它的内置函数。

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

2个回答

20
这些属性用于为在C代码中定义的Python对象启用内省。 C-API参数诊所 提供了数据,以帮助inspect模块构建Signature对象。之前不支持C-API函数的内省。
请参见内部inspect._signature_fromstr()函数,了解如何使用__text_signature__值。目前,__text_signature__ 属性是从 C-API 中对象的内部文档字符串中填充的;会对字符串进行简单的文本搜索,查找 objectname(...)\n--\n\n ,其中 \n--\n\n 是 Attribute Clinic 生成的文档字符串的典型格式。如果您想查找一些示例,请查看type 对象槽。或者您可以查看audioop 模块源代码,了解如何使用 Argument Clinic 来定义签名;在构建时运行 Argument Clinic 脚本 可以生成文档字符串(在随附的audioop.c.h 文件中)。
如果存在 __signature__ 属性,则应为 inspect.Signature() 对象;C-API 可以提供完全解析的 Signature 实例,而不是提供文本版本。

3
虽然你的答案有一个严重的错误,但C-API被称为Argument Clinic,这是对同名Monty Python短剧的引用;) - Antti Haapala -- Слава Україні
5
@Antti: 我已经告诉过你一次了。 - Martijn Pieters
2
开头仍然写着“属性诊所” :D - Antti Haapala -- Слава Україні
4
@Antti:不,它没有。抱歉,这是5分钟的争论还是半个小时的全面讨论? - Martijn Pieters
2
哦...只需要五分钟。 - Antti Haapala -- Слава Україні
啊,非常感谢您提供的audioop示例!非常有帮助。 - Christian Tismer

18

简介

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, /)'

__text_signature__ 属性用于创建 Signature 对象:

>>> inspect.signature(Random.randrange)
<Signature (self, start, stop=None, step=1, /)>

这样可以使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]]).

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