Dav*_*vid 4 python inheritance
给出以下简化代码:
from abc import ABC, abstractmethod
class Parent(ABC):
def __init__(self,*args,**kwargs):
self.parent_name = 'SuperClass'
# global hook to run before each subclass run()
def global_pre_run_hook(self):
pass
@abstractmethod
def run(self, *args, **kwargs):
raise NotImplementedError()
class Child(Parent):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.name = 'ChildClass'
def run(self):
print(f'my parent name is {self.parent_name}')
print(f'my name is {self.name}')
return 22
obj = Child()
result = obj.run()
Run Code Online (Sandbox Code Playgroud)
有没有办法添加功能,以便run()
直接调用子类方法时,首先触发父类的钩子函数?假设有一个父类和许多子类,我是否需要在每个子类的call global hook()
每个定义的开头手动添加一个?有没有一种Pythonic的方法来完成这个?run()
Parent()
绿斗篷人的答案有效,但不能被腌制!为了解决这个问题,我们需要将钩子创建移到__new__
. functools.wraps
另外,在钩子创建器中使用也是一个好主意。
import pickle
from abc import ABC, abstractmethod
from functools import wraps
def create_hook(func, hook):
@wraps(func)
def wrapper(*args, **kwargs):
hook(*args, **kwargs)
return func(*args, **kwargs)
return wrapper
class Parent(ABC):
def __new__(cls, *args, **kwargs):
cls.run = create_hook(cls.run, cls.global_pre_run_hook)
return super().__new__(cls, *args, **kwargs)
# global hook to run before each subclass run()
def global_pre_run_hook(self, *args, **kwargs):
print("Hooked")
@abstractmethod
def run(self, *args, **kwargs):
raise NotImplementedError()
class Child(Parent):
def run(self):
print(f"my parents are {self.__class__.__mro__}")
print(f"my name is {self.__class__.__name__}")
return 22
obj = Child()
result = obj.run()
pickle.dumps(obj)
Run Code Online (Sandbox Code Playgroud)