[英]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__
中操作文档字符串。 这在一定程度上可行,但会带来一些问题:
__init__
)。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.run
和Base.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.