Python 使子类自动调用超类方法
这里的上下文很简单,我正在创建一个基类,其他开发人员将对其进行子类化,他们应该实现Python 使子类自动调用超类方法,python,python-3.x,Python,Python 3.x,这里的上下文很简单,我正在创建一个基类,其他开发人员将对其进行子类化,他们应该实现test方法 现在我不希望他们在实现中调用super().test(),我该怎么做 贝娄是我尝试过的,但它不起作用 class Base(): def __init__(self): self._test() def _test(self): try: super()._test() except AttributeError: pass self.
test
方法
现在我不希望他们在实现中调用super().test()
,我该怎么做
贝娄是我尝试过的,但它不起作用
class Base():
def __init__(self):
self._test()
def _test(self):
try:
super()._test()
except AttributeError:
pass
self.test()
def test(self):
print('Base')
class One(Base):
def test(self):
print('One')
class Two(One):
def test(self):
print('Two!')
two = Two()
我要打印的是上面的代码
Base
One
Two!
没有一个或两个调用super()
我知道一个解决方案是使用uu init_subclass_uu并保留一个方法数组,但这似乎太老套了如果您只想强制从基类自动调用某些方法,
uu init_subclass_uuu
确实是一种方法。您只需在那里重写所需的方法。我会使用一些接近:
from functools import update_wrapper
from inspect import signature
class Base:
# will be overriden in subclasses
_SPECIAL_METHODS = ['test', 'test2']
def test(self):
print('Base')
def test2(self, i):
print(f'{i} in Base')
def __init_subclass__(cls):
def do_wrap(cls, method):
orig = getattr(cls, method)
# ignore methods not explicitely defined in cls
if not orig.__qualname__.startswith(cls.__qualname__): return
def wrapper(*args, **kwargs):
# first calls the method from Base with passed arguments
getattr(Base, method)(*args, **kwargs)
# then the one from the subclass
return orig(*args, **kwargs)
# keep the original signature, docstring, etc.
wrapper.__signature__ = signature(orig)
setattr(cls, method, update_wrapper(wrapper, orig))
for i in Base._SPECIAL_METHODS:
do_wrap(cls, i)
class One(Base):
def test(self):
# super().test()
print('One')
def test2(self, i):
print(f'{i} in One')
class Two(One):
def test2(self, j):
print('In Two:', j)
它给出:
>>> a = One()
>>> a.test()
Base
One
>>> a.test2(2)
2 in Base
2 in One
>>> b = Two()
>>> b.test()
Base
One
>>> b.test2(5)
5 in Base
In Two: 5
此示例使用传递给子类1的参数调用基方法,但这很容易适应。因此,为了澄清,您希望在构造时调用
测试方法链?你从来没有调用过test
,即使是在two
?@RayToal实际上在construnction上被调用只是一个例子,对我来说,无论是稍后调用还是不调用都没关系。好的,谢谢,那么这有帮助吗?或者这是一个不同的场景吗?