<p>我认为可以通过注入一个知道类层次结构的decorator来使用元类<code>__prepare__</code>方法:</p>
<pre><code>def log_docstring(fn):
print('docstring for %r is %r' % (fn, fn.__doc__))
return fn
class InheritableDocstrings(type):
def __prepare__(name, bases):
classdict = dict()
# Construct temporary dummy class to figure out MRO
mro = type('K', bases, {}).__mro__[1:]
assert mro[-1] == object
mro = mro[:-1]
def inherit_docstring(fn):
if fn.__doc__ is not None:
raise RuntimeError('Function already has docstring')
# Search for docstring in superclass
for cls in mro:
super_fn = getattr(cls, fn.__name__, None)
if super_fn is None:
continue
fn.__doc__ = super_fn.__doc__
break
else:
raise RuntimeError("Can't inherit docstring for %s: method does not "
"exist in superclass" % fn.__name__)
return fn
classdict['inherit_docstring'] = inherit_docstring
return classdict
class Animal():
def move_to(self, dest):
'''Move to *dest*'''
pass
class Bird(Animal, metaclass=InheritableDocstrings):
@log_docstring
@inherit_docstring
def move_to(self, dest):
self._fly_to(dest)
assert Animal.move_to.__doc__ == Bird.move_to.__doc__
</code></pre>
<p>印刷品:</p>
^{pr2}$
<p>当然,这种方法还有一些其他问题:
-一些分析工具(例如pyflakes)会抱怨使用(显然)未定义的<code>inherit_docstring</code>名称
-如果父类已经有一个不同的元类(例如<code>ABCMeta</code>),那么它就不起作用了。在</p>