Implementing a class property that preserves the docstring

前端 未结 2 1578
长发绾君心
长发绾君心 2021-01-19 08:09

I have a descriptor that turns a method into a property on the class level:

class classproperty(object):

    def __init__(self, getter):
        self.getter         


        
2条回答
  •  甜味超标
    2021-01-19 08:29

    Indeed, test is a property returning a string. You'd have to subclass str and give that a __doc__ attribute:

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

    Demo:

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

    Use as:

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

    Because str objects are immutable, you cannot set the __doc__ attribute in a decorator. You'd have to return a proxy object instead that fully wraps the actual return value except for the __doc__ attribute. This gets to be complex and ugly fast.

    The alternative is to put a regular property on the metaclass; the class's class:

    class MetaClass(type):
        @property
        def test(cls):
            "docstring"
            return "Test"
    
    class A(object):
        __metaclass__ = MetaClass
    

    Now A has a test property, and the docstring can be accessed as MetaClass.test.__doc__ or with type(A).test.__doc__:

    >>> A.test
    'Test'
    >>> type(A).test
    
    >>> type(A).test.__doc__
    'docstring'
    

提交回复
热议问题