浅拷贝对象时如何重新初始化属性?以UUID为例
解决UuidMixin浅拷贝时UUID重复的问题
方案一:利用__getstate__和__setstate__实现健壮的UUID重置
copy模块执行拷贝操作时,会调用对象的__getstate__获取状态,再通过__setstate__将状态恢复到新实例。我们可以在UuidMixin中重写这两个方法,确保拷贝后的实例自动生成新UUID:
import uuid import copy class UuidMixin: def __new__(cls): obj = super().__new__(cls) obj.uuid = uuid.uuid4() return obj def __getstate__(self): # 复制当前实例的状态字典 return self.__dict__.copy() def __setstate__(self, state): # 恢复实例状态后生成新UUID self.__dict__.update(state) self.uuid = uuid.uuid4() class Foo(UuidMixin): pass # 测试浅拷贝 f = Foo() f2 = copy.copy(f) print(f.uuid == f2.uuid) # 输出False
这个方案的优势:
- 不依赖
__copy__方法,即使继承链中其他类定义了__copy__,只要遵循Python序列化规范就会自动生效 - 同时支持
copy.copy()和copy.deepcopy(),无需额外处理深拷贝逻辑
方案二:兼容继承链的__copy__实现
如果更倾向于直接针对拷贝操作处理,可以通过调用父类的__copy__方法保证兼容性,避免破坏继承链中的其他逻辑:
import uuid import copy class UuidMixin: def __new__(cls): obj = super().__new__(cls) obj.uuid = uuid.uuid4() return obj def __copy__(self): # 优先调用父类的__copy__生成实例,没有则使用默认拷贝逻辑 new_obj = super().__copy__() if hasattr(super(), '__copy__') else copy.copy(super()) # 为拷贝实例生成新UUID new_obj.uuid = uuid.uuid4() return new_obj class Foo(UuidMixin): pass # 测试 f = Foo() f2 = copy.copy(f) print(f.uuid == f2.uuid) # 输出False
这种方式明确针对拷贝场景,只要父类的__copy__实现正常,就能保证继承链逻辑不被破坏。
内容的提问来源于stack exchange,提问作者user1109069
相关产品推荐
相关产品推荐

