You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浅拷贝对象时如何重新初始化属性?以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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:58:21