一方面,我们被鼓励只创建字段,而不是用模仿其他语言的额外访问器函数来包裹我们的 python 类。
另一方面,“属性文档字符串”的 PEP被拒绝。
另一方面,epydoc和sphinx支持它们。冒着提出非建设性问题的风险,在类中记录变量是否存在单一、清晰、通用的做法?
一方面,我们被鼓励只创建字段,而不是用模仿其他语言的额外访问器函数来包裹我们的 python 类。
另一方面,“属性文档字符串”的 PEP被拒绝。
另一方面,epydoc和sphinx支持它们。冒着提出非建设性问题的风险,在类中记录变量是否存在单一、清晰、通用的做法?
自从我被要求这样做以来,我将我的评论改写为答案。
通常,实例(公共)属性是不言自明的,用户使用它们不需要文档。属性的名称和上下文足以明确属性是什么,您可以在类的文档中添加一些关于如何处理它的文档。
在某些情况下,您可能最终希望为用户提供属性的访问权限,但该属性不够自我解释和/或其处理需要注意(因为如果处理不当,它可能会“搞砸” )。
例如,您可能希望让用户知道属性应该具有特定的“接口”以允许使用它。或者您必须解释该属性必须满足的条件。
在这种情况下,将文档与课程的文档放在一起并不是一个好主意,因为课程的文档越来越长,并且解释了很多非常具体的知识。
简单且我认为更优雅的解决方案是使用属性。属性允许您向属性添加文档字符串,并为您提供一种实际控制对它的访问的方法,从而使类更加健壮。
如果你必须处理很多属性,那么编写几十个属性可能会很麻烦,但你仍然可以动态添加它们,例如使用装饰器。这很有效,特别是如果您只想添加一个文档字符串,始终使用相同类型的 getter/setter。
例如你可以写:
def set_properties(names_to_docs):
def decorator(cls):
for name, doc in names_to_docs.items():
prop = property((lambda self: getattr(self, '_{}'.format(name))),
(lambda self, val: setattr(self, '_{}'.format(name), val),
doc=doc)
setattr(cls, name, prop)
return cls
return decorator
并像这样使用它:
>>> @set_properties({'a': 'This is a', 'b': 'This is b'})
>>> class Test:
... def __init__(self):
... self._a = 1
... self._b = 2
...
>>> print(Test.a.__doc__)
This is a
>>> Test().a
1
Lukas Graf 在评论中指出,您可以使用 Zope.interface 创建一个简单描述具体类的类,这使您有机会将文档字符串添加到属性中。这可能是另一种选择。我没有使用 Zope.interface 的经验,所以我无法确切地知道你能做什么,如何,以及它最终如何与自动文档程序交互。