我正在使用自定义元类来装饰类的方法。但是,它目前仅修饰直接在类中定义的方法,而不修饰从父类继承的方法。
我的课程结构如下:
class Abstract1(ABC):
class A(Abstract1):
def fun1(self):
def fun2(self):
class DecoMeta(ABCMeta):
class B(A, metaclass=DecoMeta):
def hello(self):
我的 DecoMeta 类如下所示:
class DecoMeta(ABCMeta):
""" Decorator class
"""
def __new__(mcs, name: str, bases: tuple, attrs: dict):
for attr_name, attr_value, in attrs.items():
if isinstance(attr_value, types.FunctionType):
attrs[attr_name] = mcs.deco(attr_value)
return super(DecoMeta, mcs).__new__(mcs, name, bases, attrs)
@classmethod
def deco(mcs, func):
""" Decorate func
"""
async def wrapper(*args, **kwargs):
result = await func(*args, **kwargs)
# print(args[0].__dict__.keys())
args[0].some_function(). # i.e. self.some_function()
return result
return wrapper
当我打印 args[0].dict.keys() 时,它只打印出类 B 中定义的函数。这意味着 decoMeta 只装饰这些函数(在本例中为 hello())。我想使用这个 DecoMeta 来装饰父类中定义的所有函数,即 A 类(如 fun1() 和 fun2())。有办法做到吗?
您还必须将
A
注册到元类。
实现此目的的一种方法是将元类也传递给父类:
class Abstract1(ABC):
pass
class DecoMeta(ABCMeta):
pass
class A(Abstract1, metaclass=DecoMeta):
def fun1(self):
pass
def fun2(self):
pass
class B(A, metaclass=DecoMeta):
def hello(self):
pass
修改后的
DecoMeta
,只是为了显示attr_name
:
class DecoMeta(ABCMeta):
""" Decorator class
"""
def __new__(mcs, name: str, bases: tuple, attrs: dict):
for attr_name, attr_value, in attrs.items():
if isinstance(attr_value, types.FunctionType):
print(attr_name)
# attrs[attr_name] = mcs.deco(attr_value)
return super(DecoMeta, mcs).__new__(mcs, name, bases, attrs)
B()
输出
fun1
fun2
hello