On Fri, Jun 10, 2011 at 5:05 AM, Tim Chase <python.l...@tim.thechases.com> wrote: > On 06/09/2011 01:22 AM, Eric Snow wrote: >> >> Sometimes when using class inheritance, I want the overriding methods >> of the subclass to get the docstring of the matching method in the >> base class. You can do this with decorators (after the class >> definition), with class decorators, and with metaclasses [1]. > > While asking for __doc__ ponies and picking colors for bike-sheds, in a > similar vein, I've occasionally wanted to do something like > > class Foo: > @property > def __doc__(self): > return dynamically_generated_string > # perhaps using introspection >
However, on the class the property is just a property object (a descriptor). If you want to have a dynamic doc on the class then you have to do it on a metaclass: class Meta(type): @property def __doc__(cls): if not hasattr(cls, "_mydoc"): cls._mydoc = None return cls._mydoc class X(metaclass=Meta): pass X.__doc__ # None X._mydoc # None X._mydoc = "test" X.__doc__ # 'test' X().__doc__ # None The only problem, as seen in the last line, is that the __doc__ on instances is not inherited on instances of the class. Object attribute lookup only looks to the type's __dict__ for inheritance, and not the types's type. However, that should not be that hard to work around. -eric > This would have been most helpful in things like generating help (like in > command-line parsers), where the doc-string can introspect the class and > learn about its methods at runtime. Some things seem to inherit, some don't, > and help() doesn't seem to pick up on any of the dynamically-defined __doc__ > properties. Test code below. > > -tkc > > > > from datetime import datetime > from sys import stdout > class Base(object): > "Base docstring" > @property > def __doc__(self): > return datetime.now().strftime('%c') > > class WithDoc(Base): > "WithDoc docstring" > pass > > class WithoutDoc(Base): pass > > base = Base() > has = WithDoc() > lacks = WithoutDoc() > > for test in ( > "help(base)", # why not in help? > "help(has)", # expected > "help(lacks)", # why not in help? > "help(Base)", > "help(WithDoc)", # expected > "help(WithoutDoc)", > "stdout.write(repr(base.__doc__))", # works > "stdout.write(repr(has.__doc__))", # expected > "stdout.write(repr(lacks.__doc__))", # where'd it go? > "stdout.write(repr(Base.__doc__))", # expected > "stdout.write(repr(WithDoc.__doc__))", # expected > "stdout.write(repr(WithoutDoc.__doc__))", # what? > ): > print test > eval(test) > print > -- http://mail.python.org/mailman/listinfo/python-list