我正在写一个轻量级类,它的属性是公共可访问的,只有在特定的示例化中才会被覆盖。在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)
这将导致类的docstring包含初始的标准docstring部分,以及通过对__doc__
的扩展赋值为每个属性添加的行。
尽管docstring style guidelines没有明确禁止这种风格,但也没有将其作为选项提及。这里的优点是,它提供了一种将属性与其定义一起记录的方法,同时仍然创建了一个可表示的类docstring,并且避免了必须编写重复docstring中信息的注解。我仍然有点恼火,因为我实际上必须编写两次属性;我正在考虑使用docstring中值的字符串表示,至少可以避免重复默认值。
这是对特别社区惯例的严重违反吗?可以吗?有更好的方法吗?例如,可以创建一个包含属性的值和文档字符串的字典,然后将内容添加到类__dict__
和文档字符串的类声明末尾;这将减少键入属性名称和值两次的需要。edit:我认为最后一个想法实际上是不可能的,至少在没有从数据动态构建整个类的情况下是不可能的,这似乎是一个非常糟糕的想法,除非有其他原因。
我对python还是个新手,还在研究编码风格的细节,所以不相关的批评也是受欢迎的。
4条答案
按热度按时间2wnc66cl1#
简而言之:类属性不能像类和函数那样拥有文档字符串。
为了避免混淆,术语 property 在python中有一个特定的含义。你所谈论的是我们所称的 class attributes。因为它们总是通过它们的类来操作,所以我发现在类的doc字符串中记录它们是有意义的。类似于这样:
我认为这比示例中的方法更容易理解,如果我真的希望属性值的副本出现在文档字符串中,我会将它们放在每个属性描述的旁边或下面。
请记住,在Python中,文档字符串是它们所记录的对象的实际成员,而不仅仅是源代码注解。由于类属性变量本身不是对象,而是对对象的引用,因此它们无法保存自己的文档字符串。我猜您可以为引用上的文档字符串做一个案例,也许是描述“什么应该在这里”而不是“什么实际在这里”,但是我发现在包含类的文档字符串中这样做很容易。
ej83mcc02#
您引用PEP257:文档字符串惯例,在“什么是文档字符串”一节中规定:
出现在Python代码中其他地方的字符串也可以作为文档,它们不能被Python字节码编译器识别,也不能作为运行时对象属性访问(也就是说,不能赋值给
__doc__
),但是软件工具可以提取两种类型的额外文档字符串:在模块、类或
__init__
方法的顶层进行简单赋值之后立即出现的字符串字面量称为“属性文档字符串”。这在PEP 258中有更详细的解释:属性文档字符串部分。如上所述,属性不是可以拥有
__doc__
的对象,因此它们不会出现在help()
或pydoc中。这些文档字符串只能用于生成的文档。它们在Sphinx中与autoattribute指令一起使用
Sphinx可以在赋值之前的行上使用注解,或者在赋值之后使用特殊注解,或者在定义之后使用文档字符串,这些都将被自动记录。
guykilcj3#
其他的答案非常过时。PEP-224(在Python 2.1中可用!)描述了如何将docstring用于属性,它们出现在属性之后,很奇怪。
它也适用于如下类型注解:
VSCode支持显示这些。
3vpjnl9f4#
你可能会滥用属性来达到这个效果,属性包含getter、setter、deleter * 和docstring*,天真的话,这会变得非常冗长:
然后,您将拥有一个属于C.x的文档字符串:
要对许多属性执行此操作是很麻烦的,但您可以设想一个helper函数myprop:
然后,调用Pythons interactive
help
将给予:我觉得这应该就是你想要的。
编辑:我现在意识到,我们也许可以完全避免将第一个参数传递给
myprop
,因为内部名称并不重要。如果myprop
的后续调用可以以某种方式相互通信,它可以自动决定一个长的和不太可能的内部属性名称。我确信有一些方法可以实现这一点,但我不确定是否值得。