I have a descriptor that turns a method into a property on the class level:
class classproperty(object):
def __init__(self, getter):
self.getter
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
<property object at 0x10757d158>
>>> type(A).test.__doc__
'docstring'
If you jump through a few hoops, it can be retrieved, but not directly through the property itself like A.test.__doc__
because of the way descriptors work.
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