如何克隆Python类对象(非实例),自定义属性方法且关联原类?
克隆Python类并同步原类未修改属性的解决方案
需求明确
克隆类A得到NewA,仅修改NewA的指定属性/方法,未修改部分需在原类A更新时自动同步,同时兼容元类、__slots__、自定义init_subclass等复杂场景,且不能使用继承方式。
实现方案
利用Python的属性访问机制,创建一个代理原类属性的新类,通过类级别的__getattr__和__setattr__实现自定义属性优先、未定义属性同步原类的逻辑,同时保留原类的元类特性。
克隆函数代码
import types def clone_class(cls, new_name=None): # 确定新类名称,默认在原类名前加Cloned前缀 new_name = new_name or f"Cloned{cls.__name__}" # 创建空的新类,不继承原类 cloned_cls = types.new_class(new_name, bases=(), exec_body=lambda ns: None) # 同步原类的元类,确保元类逻辑生效 cloned_cls.__class__ = cls.__class__ # 存储新类的自定义属性 _custom_attrs = {} # 类级别的属性获取:优先返回自定义属性,否则代理原类 def __getattr__(name): return getattr(cls, name) # 类级别的属性设置:仅修改新类的自定义属性,不影响原类 def __setattr__(name, value): _custom_attrs[name] = value cloned_cls.__dict__[name] = value # 绑定属性访问方法到新类 cloned_cls.__getattr__ = __getattr__ cloned_cls.__setattr__ = __setattr__ # 同步原类的__slots__(如果存在) if hasattr(cls, '__slots__'): cloned_cls.__slots__ = cls.__slots__ # 同步其他关键类属性(可选,增强一致性) for attr in ('__module__', '__qualname__'): if hasattr(cls, attr): setattr(cloned_cls, attr, getattr(cls, attr)) return cloned_cls
使用示例
# 定义原类 class A: x = 10 def __init__(self, y): self.y = y def foo(self): return self.x + self.y # 克隆得到NewA NewA = clone_class(A) # 装饰NewA的__init__方法,不修改原类A def decorator(func): def wrapped(self, y): print("NewA初始化被调用") func(self, y) return wrapped NewA.__init__ = decorator(A.__init__) # 测试实例化与方法调用 a_inst = A(5) print(a_inst.foo()) # 输出15 new_a_inst = NewA(5) # 输出"NewA初始化被调用" print(new_a_inst.foo()) # 输出15 # 修改原类A的属性,验证同步效果 A.x = 20 print(a_inst.foo()) # 输出25 print(new_a_inst.foo()) # 输出25,自动同步原类更新 # 测试__slots__兼容 class B: __slots__ = ('a', 'b') def __init__(self, a, b): self.a = a self.b = b NewB = clone_class(B) b_inst = NewB(1, 2) print(b_inst.a, b_inst.b) # 输出1 2 # 测试元类兼容 class Meta(type): def __new__(cls, name, bases, attrs): attrs['meta_value'] = 99 return super().__new__(cls, name, bases, attrs) class C(metaclass=Meta): pass NewC = clone_class(C) print(NewC.meta_value) # 输出99,元类逻辑正常生效
方案优势
- 自动同步原类更新:未修改的属性通过
__getattr__代理访问原类,原类属性变化时新类自动同步。 - 兼容复杂场景:自动继承原类元类,同步
__slots__,无需手动处理描述符、类方法、静态方法等边缘情况。 - 隔离修改:新类的属性修改仅作用于自身,不会影响原类。
- 非继承实现:避免了继承带来的
isinstance判断、方法重写优先级等问题,完全符合克隆需求。
内容的提问来源于stack exchange,提问作者Vahid Zee
相关产品推荐
相关产品推荐

