10

我有具有对象属性的 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)或尝试Foo在 Sphinx 中记录,则不会显示self.basepathandself.availableruns属性。这对我们 API 的用户来说是个问题。

我尝试寻找一种标准方法来确保解析器可以找到这些“动态声明的”属性(最好是文档字符串),但到目前为止还没有运气。有什么建议么?谢谢。

4

2 回答 2

11

我尝试寻找一种标准方法来确保解析器可以找到这些“动态声明的”属性(最好是文档字符串),但到目前为止还没有运气。有什么建议么?

它们永远不会被任何解析器“检测到”。

Python 有setattr. 从任何意义上说,完整的属性集永远都不是“可检测的”。

您绝对必须在文档字符串中描述它们。

[除非你想做一堆元编程来从你收集的东西inspect或其他东西中生成文档字符串。即使那样,一旦您开始使用,您的“解决方案”将是不完整的setattr。]

class Foo(object):
    """
    :ivar basepath:
    :ivar availableruns:
    """
    def __init__(self, base):
于 2010-10-18T14:20:13.413 回答
2

您可以定义一个与实例变量同名的类变量。然后,当您设置它时,该类变量将被实例变量遮蔽。例如:

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

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

事实上,如果实例变量有一个有用的不可变默认值(例如 None 或空元组),那么您可以通过不设置变量 if 应该有其默认值来节省一点内存。当然,如果您谈论的是您可能想要删除的实例变量(例如,del foo.availableruns),这种方法将不起作用——但我发现这不是一个很常见的情况。

如果您使用的是 sphinx,并且设置了“自动属性”,那么这应该得到适当的记录。或者,根据您正在做的事情的上下文,您可以直接使用 Sphinx.. py:attribute::指令。

于 2011-07-18T18:58:48.827 回答