int*_*ted 101 python documentation docstring class class-attributes
我正在编写一个轻量级类,其属性旨在可公开访问,并且有时仅在特定实例中被覆盖.在Python语言中没有为类属性或任何类型的属性创建文档字符串的规定.记录这些属性的可接受方式是什么?目前我正在做这样的事情:
class Albatross(object):
"""A bird with a flight speed exceeding that of an unladen swallow.
Attributes:
"""
flight_speed = 691
__doc__ += """
flight_speed (691)
The maximum speed that such a bird can attain.
"""
nesting_grounds = "Raymond Luxury-Yacht"
__doc__ += """
nesting_grounds ("Raymond Luxury-Yacht")
The locale where these birds congregate to reproduce.
"""
def __init__(self, **keyargs):
"""Initialize the Albatross from the keyword arguments."""
self.__dict__.update(keyargs)
Run Code Online (Sandbox Code Playgroud)
这将导致类的docstring包含初始标准docstring部分,以及通过扩充赋值为每个属性添加的行__doc__.
虽然在文档字符串样式指南中似乎没有明确禁止这种样式,但它也没有作为选项提及.这里的优点是它提供了一种方法来记录属性及其定义,同时仍然创建一个可呈现的类docstring,并避免编写重复来自docstring的信息的注释.我仍然有点生气,我必须实际写两次属性; 我正在考虑使用docstring中值的字符串表示来至少避免重复默认值.
这是否是对特设社区公约的毁灭性违反?好吗?有没有更好的办法?例如,可以创建包含属性值和文档字符串的字典,然后__dict__在类声明的末尾将内容添加到类和docstring中; 这样可以减少两次输入属性名称和值的需要. 编辑:我认为,这最后一个想法实际上是不可能的,至少不是没有从数据动态构建整个类,这似乎是一个非常糟糕的想法,除非有其他理由这样做.
我对python很新,并且仍在研究编码风格的细节,所以也欢迎无关的批评.
ʇsә*_*ɹoɈ 75
为避免混淆:术语属性在python中具有特定含义.你所说的是我们所谓的类属性.由于他们总是通过他们的班级采取行动,我发现在类的doc字符串中记录它们是有意义的.像这样的东西:
class Albatross(object):
"""A bird with a flight speed exceeding that of an unladen swallow.
Attributes:
flight_speed The maximum speed that such a bird can attain.
nesting_grounds The locale where these birds congregate to reproduce.
"""
flight_speed = 691
nesting_grounds = "Throatwarbler Man Grove"
Run Code Online (Sandbox Code Playgroud)
我认为眼睛比你的例子中的方法容易得多.如果我真的想要在doc字符串中显示属性值的副本,我会将它们放在每个属性的描述旁边或下面.
请记住,在Python中,doc字符串是他们记录的对象的实际成员,而不仅仅是源代码注释.由于类属性变量本身不是对象,而是对对象的引用,因此它们无法保存自己的文档字符串.我想你可以为引用上的doc字符串做一个案例,或许可以描述"应该去哪里"而不是"实际上是什么",但我发现在包含类doc字符串中这样做很容易.
Tim*_*mmm 54
其他答案已经非常过时了。PEP-257描述了如何使用属性的文档字符串。奇怪的是,他们在属性之后出现:
\n\n\nPython 代码中其他地方出现的字符串文字也可以充当文档。它们不被Python字节码编译器识别,并且不能作为运行时对象属性访问(即不分配给__doc__),但是软件工具可以提取两种类型的额外文档字符串:
\n\n
\n- 在模块、类或 __init__ 方法顶层的简单赋值之后立即出现的字符串文字称为 \xe2\x80\x9cattribute docstrings\xe2\x80\x9d。
\n
class C:\n "class C doc-string"\n\n a = 1\n "attribute C.a doc-string (1)"\n\n b = 2\n "attribute C.b doc-string (2)"\nRun Code Online (Sandbox Code Playgroud)\n它也适用于这样的类型注释:
\nclass C:\n "class C doc-string"\n\n a: int\n "attribute C.a doc-string (1)"\n\n b: str\n "attribute C.b doc-string (2)"\nRun Code Online (Sandbox Code Playgroud)\nVSCode 支持显示这些。
\nmar*_*rcz 28
您引用了PEP257:文档字符串约定,它在什么是文档字符串中说明:
Python代码中其他地方出现的字符串文字也可以作为文档.它们不被Python字节码编译器识别,并且不能作为运行时对象属性访问(即未分配给__doc__),但软件工具可以提取两种类型的额外文档字符串:
在模块,类或__init__方法的顶层进行简单赋值后立即出现的字符串文字称为"属性docstrings".
这在PEP 258:属性文档字符串中有更详细的解释.如上所述ʇsәɹoɈ.属性不是可以拥有__doc__的对象,因此它们不会出现在help()pydoc中.这些文档字符串只能用于生成的文档.
它们在Sphinx中与指令autoattribute一起使用
Sphinx可以在赋值之前的行上使用注释,也可以在赋值之后使用特殊注释,或者在将自动记录的定义之后使用docstring.
ger*_*rit 11
您可以滥用属性来达到此效果.属性包含getter,setter,deleter 和docstring.天真地,这将变得非常冗长:
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""Docstring goes here."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
Run Code Online (Sandbox Code Playgroud)
然后你将有一个属于Cx的文档字符串:
In [24]: print(C.x.__doc__)
Docstring goes here.
Run Code Online (Sandbox Code Playgroud)
为许多属性执行此操作非常麻烦,但您可以设想一个辅助函数myprop:
def myprop(x, doc):
def getx(self):
return getattr(self, '_' + x)
def setx(self, val):
setattr(self, '_' + x, val)
def delx(self):
delattr(self, '_' + x)
return property(getx, setx, delx, doc)
class C:
a = myprop("a", "Hi, I'm A!")
b = myprop("b", "Hi, I'm B!")
In [44]: c = C()
In [46]: c.b = 42
In [47]: c.b
Out[47]: 42
In [49]: print(C.b.__doc__)
Hi, I'm B!
Run Code Online (Sandbox Code Playgroud)
然后,调用Pythons交互help将给出:
Help on class C in module __main__:
class C
| Data descriptors defined here:
|
| a
| Hi, I'm A!
|
| b
| Hi, I'm B!
Run Code Online (Sandbox Code Playgroud)
编辑:我现在意识到我们可以避免需要传递第一个参数myprop,因为内部名称无关紧要.如果后续调用myprop可以某种方式相互通信,它可以自动决定一个长且不太可能的内部属性名称.我确信有办法实现这一点,但我不确定它们是否值得.