Python中实现可包装已有Base类实例、无属性拷贝且可识别为Base的类包装器
实现方案
核心思路
- 让
Wrapper显式继承Base类,天然满足isinstance类型校验要求,这里的继承仅用于类型识别,Wrapper初始化时不会调用Base的构造方法,不会重复初始化Base属性,完全复用传入的已构造完成的实例,适配已有实例的包装需求 - 内部持有传入的
Base实例引用,不做任何属性拷贝,完全复用原实例字段 - 通过重写魔术方法
__getattr__和__setattr__实现属性/方法的自动转发,Wrapper自定义成员优先级高于原Base实例成员 - 天然支持包装
Base的所有子类实例,无需针对子类做适配修改
完整实现代码
class Base: def __init__(self, base_param_1): self.base_param_1 = base_param_1 def base_method_1(self, val): return f"base method return: {val}" class Wrapper(Base): def __init__(self, cls_instance, *args, **kwargs): # 用object原生方法存储原实例引用,避免触发自定义__setattr__导致死循环 object.__setattr__(self, '_base_inst', cls_instance) # 初始化Wrapper自定义参数 self.wrapper_param_1 = kwargs.get('wrapper_param_1', 'default_wrapper_val') def wrapper_method_1(self, val): return f"wrapper method return: {val}" def __getattr__(self, name): # 自身不存在的属性,自动转发到原Base实例获取 return getattr(self._base_inst, name) def __setattr__(self, name, value): # Wrapper自定义属性存储在自身实例,其他属性直接写入原Base实例 if name in ('wrapper_param_1', '_base_inst'): # 新增自定义属性时补充到该列表即可 object.__setattr__(self, name, value) else: setattr(self._base_inst, name, value)
效果验证
# 构造原Base实例 base_obj = Base("base_param_value") # 按预期用法构造Wrapper实例 wrapper_obj = Wrapper(base_obj, wrapper_param_1="custom_wrapper_val") # 1. 正常访问Base类属性和方法 print(wrapper_obj.base_param_1) # 输出 base_param_value print(wrapper_obj.base_method_1("test")) # 输出 base method return: test # 2. 正常访问Wrapper自定义属性和方法 print(wrapper_obj.wrapper_param_1) # 输出 custom_wrapper_val print(wrapper_obj.wrapper_method_1("test")) # 输出 wrapper method return: test # 3. 验证无属性拷贝:修改wrapper上的Base属性,原实例同步变更 wrapper_obj.base_param_1 = "new_base_val" print(base_obj.base_param_1) # 输出 new_base_val # 4. 验证类型识别 print(isinstance(wrapper_obj, Base)) # 输出 True
内容的提问来源于stack exchange,提问作者spiridon_the_sun_rotator
相关产品推荐
相关产品推荐

