繁体   English   中英

在基础 class 中操作 function 文档字符串和签名

[英]Manipulating function docstring and signature in base class

我有一个抽象基础 class Base ,它提供了一个需要由派生类实现的抽象方法_run() ,以及一个将调用_run()并执行所有派生类共有的额外工作的方法run() .

在所有派生类中,我为_run()方法设置 function 文档字符串。 由于这个 function 不是公共 API 的一部分,我想要相同的文档字符串(和 function 签名)来代替run()方法。

考虑以下示例:

import inspect
from abc import ABC, abstractmethod

class Base(ABC):
    @abstractmethod
    def _run(self):
        return

    def run(self, *args, **kwargs):
        """old_doc"""
        return self._run(*args, **kwargs)

class Derived(Base):
    def _run(self):
        """new_doc"""
        return

我最初的想法是在Base.__init__Base.__new__中操作文档字符串。 这在一定程度上可行,但会带来一些问题:

  1. 我希望能够在派生类中覆盖这两种方法(至少__init__ )。
  2. 这需要在文档字符串可用之前实例化 class。
  3. 通过在实例化派生 class 时为Base.run设置文档字符串,它实际上会为所有派生类设置文档字符串。
class Base(ABC):
    def __init__(self):
        type(self).run.__doc__ = type(self)._run.__doc__
        type(self).run.__signature__ = inspect.signature(type(self)._run)

    ...

我所希望的:

>>> Derived.run.__doc__
'new_doc'

到目前为止我得到了什么:

>>> Derived.run.__doc__
'old_doc'
>>> Derived().run.__doc__
'new_doc'

有什么解决办法吗?

不要修改Base.run的文档字符串; 相反,记录它的作用:它调用一个子类定义的方法。

class Base(ABC):
    @abstractmethod
    def _run(self):
        "Must be replaced with actual code"
        return

    def run(self, *args, **kwargs):
        """Does some setup and runs self._run"""
        return self._run(*args, **kwargs)

class Derived(Base):
    def _run(self):
        """Does some work"""
        return

无需为Derived.run生成新的文档字符串,因为Derived.runBase.run评估为完全相同的 object:由Base定义的run方法。 Inheritance 不会改变Base.run所做的事情,因为它是从Derived的实例而不是Base的实例调用的。

我想出的最好的解决方法是创建一个装饰器:

from abc import ABC, abstractmethod

class Base(ABC):
    @abstractmethod
    def run(self, *args, **kwargs):
        """old_doc"""
        return self._run(*args, **kwargs)

def extra_work(func):
    # Do some extra work and modify func.__doc__
    ...
    return func

class Derived(Base):
    @extra_work
    def run(self):
        """new_doc"""
        return

这样,额外的工作仍然可以在派生的 class 之外定义,以避免在从Base派生的每个 class 中重复它,并且我能够自动更新文档字符串以反映添加的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM