使用一个方法的文档字符串自动覆盖另一个方法的文档字符串

5 投票
5 回答
3394 浏览
提问于 2025-04-11 09:15

问题是:我有一个类,这个类里面有一个模板方法叫做 execute,它会调用另一个方法 _execute。子类应该重写 _execute 方法来实现一些特定的功能。这些功能应该在 _execute 的文档字符串中进行说明。

高级用户可以创建自己的子类来扩展这个库。但是,其他使用这个子类的用户应该只使用 execute 方法,这样如果他们使用 help(execute) 的话,就看不到正确的文档字符串。

所以,如果能修改基类,让子类中的 execute 的文档字符串自动替换成 _execute 的文档字符串,那就太好了。有没有什么好的方法可以做到这一点呢?

我在考虑使用元类来实现这个功能,这样用户就完全看不到这些变化。

5 个回答

1

看看functools.wraps()这个装饰器,它可以完成所有这些功能。不过我不太确定你是否能让它在正确的环境中运行。

2

有没有什么原因让你不能直接覆盖基类的 execute 函数呢?

class Base(object):
    def execute(self):
        ...

class Derived(Base):
    def execute(self):
        """Docstring for derived class"""
        Base.execute(self)
        ...stuff specific to Derived...

如果你不想这样做:

方法对象不支持修改 __doc__ 属性,所以你必须在实际的函数对象中更改 __doc__。因为你不想覆盖基类中的那个,你就得给每个子类自己复制一份 execute

class Derived(Base):
    def execute(self):
        return Base.execute(self)

    class _execute(self):
        """Docstring for subclass"""
        ...

    execute.__doc__= _execute.__doc__

但这就像是绕了个弯子来重新定义 execute……

5

好吧,如果你不介意在子类中复制原来的方法,你可以使用下面这个技巧。

import new

def copyfunc(func):
    return new.function(func.func_code, func.func_globals, func.func_name,
                        func.func_defaults, func.func_closure)

class Metaclass(type):
    def __new__(meta, name, bases, attrs):
        for key in attrs.keys():
            if key[0] == '_':
                skey = key[1:]
                for base in bases:
                    original = getattr(base, skey, None)
                    if original is not None:
                        copy = copyfunc(original)
                        copy.__doc__ = attrs[key].__doc__
                        attrs[skey] = copy
                        break
        return type.__new__(meta, name, bases, attrs)

class Class(object):
    __metaclass__ = Metaclass
    def execute(self):
        '''original doc-string'''
        return self._execute()

class Subclass(Class):
    def _execute(self):
        '''sub-class doc-string'''
        pass

撰写回答