gpt4 book ai didi

python - 包装python父类(super class)的所有方法

转载 作者:行者123 更新时间:2023-12-05 02:45:34 25 4
gpt4 key购买 nike

如果我不能更改它的代码,有没有办法包装父类(super class)的所有方法?

作为一个最小的工作示例,请考虑这个基类 Base,它有许多返回其自身新实例的方法,以及子类 Child

class Base:

def __init__(self, val):
self.val = val

def newinst_addseven(self):
return Base(self.val + 7)

def newinst_timestwo(self):
return Base(self.val * 2)

# ...

class Child(Base):

@property
def sqrt(self):
return math.sqrt(self.val)

这里的问题是调用 childinstance.newinst_addseven() 返回 Base 的实例,而不是 Child

有没有办法包装 Base 类的方法以强制返回 Child 类型的值?

像这样的包装器:

def force_child_i(result):
"""Turn Base instance into Child instance."""
if type(result) is Base:
return Child(result.val)
return result

def force_child_f(fun):
"""Turn from Base- to Child-instance-returning function."""
def wrapper(*args, **kwargs):
result = fun(*args, **kwargs)
return force_child_i(result)
return wrapper

非常感谢!


PS:我目前做的,是看Base的源码,直接把方法添加到Child,不太好维护:

Child.newinst_addseven = force_child_f(Base.newinst_addseven)
Child.newinst_timestwo = force_child_f(Base.newinst_timestwo)

最佳答案

一种选择是使用元类:

class ChildMeta(type):
def __new__(cls, name, bases, dct):
child = super().__new__(cls, name, bases, dct)
for base in bases:
for field_name, field in base.__dict__.items():
if callable(field):
setattr(child, field_name, force_child(field))
return child


class Child(Base, metaclass=ChildMeta):
pass

它将自动用您的force_child 装饰器包装所有Base 的方法。

关于python - 包装python父类(super class)的所有方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65917217/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com