如何使Python/Sphinx文档中的对象属性仅在__init__中声明?

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)或者尝试在Sphinx中记录Foo,那么self.basepathself.availableruns属性将不会显示。这对我们API的用户来说是个问题。
我已经尝试搜索一种标准方法来确保解析器可以找到这些“动态声明”的属性(最好是有docstring),但是目前还没有找到。有什么建议吗?谢谢。
2个回答

11
我已经尝试寻找一种标准方法来确保解析器可以找到这些“动态声明”的属性(最好还能有文档字符串),但是到目前为止没有找到。有什么建议吗?它们无法被任何解析器“检测”到。Python有setattr。在任何意义上,完整的属性集都不可“检测”。你必须在文档字符串中描述它们。除非你想进行一堆元编程来从inspect等收集的东西生成文档字符串。即使这样,只要你开始使用setattr,你的“解决方案”也会不完整。
class Foo(object):
    """
    :ivar basepath:
    :ivar availableruns:
    """
    def __init__(self, base):

但这意味着它们将与其他方法平等地记录,我认为这显着提高了文档的质量。如果这不会影响性能或使代码难以理解,我愿意再多做一点工作。这就是最初问题的重点:我相信我可以找到一种方法来实现它,但我想知道是否有一种(事实上的)标准方法可以最小化缺点。 - andybuckley
1
如果有(事实上的)标准方法,是的。:ivar name: 是标准方法。创建一堆属性不会“显著提高文档质量”。它不会以任何方式改善比 :ivar name: 更好的文档。而且你将为了没有更好的文档而做大量的工作。 - S.Lott
“它们永远不可能被任何解析器“检测”。”真的吗?我至少用过一个可以很好地检测它们的Python IDE。 - Joe White
2
@Joe White:只有那些因为 self. 引用在代码检查中显而易见的子集。创建无法检测到的属性非常容易。使用 __getattr____getattribute__ 将阻止 IDE 检测。 - S.Lott
@S.Lott: 但是 Sphinx 明确承诺会查找 self.foo 属性,但这个功能对我来说充其量只能偶尔使用… - Kevin
显示剩余3条评论

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 ::指令。


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