Did a bit of looking around for you, no dice because it's something fundamentally broken and wasn't fixed until Python 3.3. So if you plan to release your program for >3.3, __doc__
attributes will be mutable.
That however doesn't seem to help you, but there are ways to more cleverly beat this problem into submission by simply provide a __doc__
property in the metaclass.
class Meta(type):
@property
def __doc__(self):
return self.attributes_string()
class Foo(object):
"""My doc string
"""
__metaclass__ = Meta
@classmethod
def default_attributes(cls):
return {'foo':'description of foo attribute',
'bar':'description of bar attribute'}
@classmethod
def attributes_string(cls):
attributes = cls.default_attributes()
result = '\nDefault Attributes:\n'
for key, value in attributes.items():
result += '%s: %s\n' % (key, value)
return result
No need to butcher that __new__
method, since attributes and properties in metaclasses will be available to subclasses and vice versa. Do a help(Foo)
and it now gives this:
CLASSES
__builtin__.object
Foo
__builtin__.type(__builtin__.object)
Meta
class Foo(__builtin__.object)
| Default Attributes:
| foo: description of foo attribute
| bar: description of bar attribute
Tested under Python 2.7.
Caveat: It will override the standard way of declaring docstrings, so you probably have to put the entire thing in there unless you also happen to override the __new__
method to put the original __doc__
out of harms way. Maybe this is what you want:
class Meta(type):
def __new__(cls, name, bases, attrs):
attrs['_doc'] = attrs.get('__doc__', '')
return super(Meta, cls).__new__(cls, name, bases, attrs)
@property
def __doc__(self):
return self._doc + self.attributes_string()
You result:
class Foo(__builtin__.object)
| My doc string
|
| Default Attributes:
| foo: description of foo attribute
| bar: description of bar attribute