Python中继承__new__返回其他类的类的实现方案
解决方案
一、不修改ExA的实现方式
原ExA的__new__直接返回固定的ExADict/ExAList实例,导致ExB继承后无法生成自身类型的实例。要让返回的实例拥有ExB的new_method,可以通过为ExB创建对应子类的方式解决:
代码实现
# 假设原ExADict、ExAList已定义且继承自ExA class ExADict(dict, ExA): pass class ExAList(list, ExA): pass # 定义ExB类 class ExB(ExA): # 定义同时继承原类型和ExB的子类 class ExBDict(ExADict, ExB): pass class ExBList(ExAList, ExB): pass def __new__(cls, obj): # 根据输入类型返回对应ExB子类的实例 if isinstance(obj, dict): return cls.ExBDict(obj) elif isinstance(obj, list): return cls.ExBList(obj) # 非dict/list类型返回默认ExB实例 return super().__new__(cls) def new_method(self): print("执行ExB的自定义方法")
原理说明
通过创建ExBDict和ExBList同时继承原类型(ExADict/ExAList)和ExB,既保留了原类型的功能,又混入了ExB的方法。在ExB的__new__中直接生成这些子类的实例,替代原ExA返回的固定类型。
二、重写ExA的简化方案
原ExA的问题在于硬编码了返回的具体类型,导致子类无法扩展。修改ExA时,可通过类属性指定对应类型,让子类按需替换:
重写后的ExA
class ExA: # 定义可被子类覆盖的类属性 dict_class = None list_class = None def __new__(cls, obj): if isinstance(obj, dict): # 若子类未指定dict_class,使用默认的ExADict target_cls = cls.dict_class or ExADict return target_cls(obj) elif isinstance(obj, list): target_cls = cls.list_class or ExAList return target_cls(obj) # 其他类型返回默认实例 return super().__new__(cls) # 原基础类型定义 class ExADict(dict, ExA): pass class ExAList(list, ExA): pass
基于重写ExA的ExB实现
class ExB(ExA): # 定义带自定义方法的子类 class ExBDict(ExADict): def new_method(self): print("执行ExB的自定义方法") class ExBList(ExAList): def new_method(self): print("执行ExB的自定义方法") # 指定ExB对应的dict/list类型 dict_class = ExBDict list_class = ExBList
原理说明
重写后的ExA通过dict_class和list_class两个类属性动态指定返回类型,子类ExB只需定义自己的扩展类型并覆盖这两个属性,就能自动返回带自定义方法的实例,无需重新实现__new__逻辑。
内容的提问来源于stack exchange,提问作者Flo
相关产品推荐
相关产品推荐

