实现保留docstring的类属性

2024-04-27 04:00:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个描述符,可以在类级别上将方法转换为属性:

class classproperty(object):

    def __init__(self, getter):
        self.getter = getter
        self.__doc__ = getter.__doc__

    def __get__(self, instance, owner):
        return self.getter(owner)

这样使用:

^{pr2}$

但是,我现在不能访问__doc__属性(这是合乎逻辑的,因为访问A.test.__doc__将获取str的{},因为A.test已经返回"Test"。在

我的最终目标是我的docstring将出现在sphinx中,因此除了访问attributes__doc__属性之外,以任何其他方式检索docstring都是不可行的。我想知道这是否有可能。在

我知道property通过返回类来解决这个问题,如果没有实例调用的话。然而,很明显,这与我的目标相悖。在

我开始担心这在Python中是不可能的。在

注意:我愿意在classproperty中使用任何特技,只要它是稳定的(即不在返回值上设置__doc__)。但是,给classproperty的用户增加任何负担是不可行的(即,他们应该只使用decorator并完成它)。在


Tags: 方法testselfdoc属性objectdef级别
2条回答

实际上,test是一个返回字符串的属性。您必须子类str,并给它一个__doc__属性:

class docstring_str(str):
    def __new__(cls, v, __doc__=''):
        s = super(docstring_str, cls).__new__(cls, v)
        s.__doc__ = __doc__
        return s

演示:

^{pr2}$

用作:

class A(object):
    @classproperty
    def test(cls):
        return docstring_str("Test", "docstring')

因为str对象是不可变的,所以您不能在decorator中设置__doc__属性。您必须返回一个proxy对象,它完全包装除了__doc__属性之外的实际返回值。这很快就会变得复杂和丑陋。在

另一种方法是在元类上添加一个正则的property;该类的类:

class MetaClass(type):
    @property
    def test(cls):
        "docstring"
        return "Test"

class A(object):
    __metaclass__ = MetaClass

现在,A有一个test属性,docstring可以作为MetaClass.test.__doc__或使用type(A).test.__doc__访问:

>>> A.test
'Test'
>>> type(A).test
<property object at 0x10757d158>
>>> type(A).test.__doc__
'docstring'

如果您跳过几个环,它可以被检索,但不能像A.test.__doc__那样直接通过属性本身来检索,因为描述符的工作方式。在

class classproperty(object):
    def __init__(self, getter):
        self.getter = getter

    def __get__(self, instance, owner):
        if instance is None:  # instance attribute accessed on class?
            return self
        return self.getter(owner)

class A(object):
    @classproperty
    def test(cls):
        "test's docstring"
        return "Test"

def docstring(cls, methodname):
    return getattr(cls, methodname).getter.__doc__

print docstring(A, 'test')  # -> test's docstring

相关问题 更多 >