如何让Python/Sphinx仅记录在__init__中声明的对象属性?

11 投票
2 回答
10082 浏览
提问于 2025-04-16 05:40

我有一些Python类,这些类的对象属性是在构造函数运行时才声明的,像这样:

class Foo(object):
    def __init__(self, base):
        self.basepath = base

        temp = []
        for run in os.listdir(self.basepath):
            if self.foo(run):
                temp.append(run)
        self.availableruns = tuple(sorted(temp))

现在,如果我使用 help(Foo) 或者尝试在Sphinx中为 Foo 编写文档,self.basepathself.availableruns 这两个属性就不会显示出来。这对使用我们API的用户来说是个问题。

我尝试过寻找一种标准的方法,确保这些“动态声明”的属性能够被解析器找到(最好还能有文档字符串),但到目前为止没有找到任何解决办法。有谁能给点建议吗?谢谢。

2 个回答

11

我试着找一种标准的方法来确保这些“动态声明”的属性可以被解析器找到(最好还能有文档说明),但到现在为止还没有找到合适的办法。有什么建议吗?

这些属性永远无法被任何解析器“检测到”。

在Python中有个叫做setattr的东西。所有的属性在任何意义上都不会被“检测到”。

你必须在文档说明中描述这些属性。

[除非你想做一些元编程,从inspect等工具收集信息来生成文档说明。即使这样,你的“解决方案”也会不完整,因为一旦你开始使用setattr,情况就会变得复杂。]

class Foo(object):
    """
    :ivar basepath:
    :ivar availableruns:
    """
    def __init__(self, base):
2

你可以定义一个类变量,名字和实例变量一样。这样,当你给实例变量赋值时,类变量就会被“遮蔽”,也就是说,实例变量会覆盖掉类变量的值。例如:

class Foo(object):
    #: Doc comment for availableruns
    availableruns = ()

    def __init__(self, base):
        ...
        self.availableruns = tuple(sorted(temp))

其实,如果实例变量有一个有用的不可变默认值(比如 None 或者空元组),那么如果这个变量应该保持默认值,你可以省点内存,不用去设置它。当然,如果你想删除这个实例变量(比如用del foo.availableruns),这种方法就不太适用了——不过我觉得这种情况并不常见。

如果你在使用 sphinx,并且设置了“autoattribute”,那么这个内容应该会被适当地记录下来。或者,根据你正在做的事情的上下文,你也可以直接使用 Sphinx 的.. py:attribute::指令。

撰写回答