Python copy模块中opaque object是什么?自定义__deepcopy__有哪些注意事项?
关于memo字典作为不透明对象的含义
这里的「不透明」不是指技术上你不能读写这个字典的内容,而是你不需要、也不应该去关心或修改它的内部存储逻辑:
copy模块仅对外承诺memo可以作为参数原样传递给嵌套的deepcopy调用,不承诺memo的键值格式会长期保持稳定。如果你为了实现某些逻辑硬编码读写memo的内部内容,后续Python版本更新调整memo的实现逻辑时,你的代码会直接出现兼容问题。
简单来说你把它当成看不懂内容的黑盒就好,只负责传递,不要碰内部的内容。
自定义类实现__deepcopy__()的注意事项
- 必须接收第二个参数
memo,所有嵌套调用copy.deepcopy的场景都要把这个memo原封不动传入,既可以避免循环引用导致的无限递归,也能保证同一个对象在嵌套结构中只会被拷贝一次。 - 创建完当前类的新实例后,第一时间将新实例写入
memo:memo[id(self)] = 新实例,避免当前对象自身存在循环引用时(比如类属性指向自己)出现重复创建、递归死循环的问题。 - 所有可变属性都要通过
copy.deepcopy(原属性, memo)的方式拷贝到新实例,不要直接手动赋值可变对象,否则会失去深拷贝的意义。 - 完全不要操作memo的其他内容,不要读取、修改memo中除了你自己写入的当前实例之外的任何值,避免破坏深拷贝的默认逻辑。
- 如果你的类包含不可拷贝的特殊资源(比如打开的文件句柄、网络连接、线程锁等),需要自行处理这部分资源的逻辑:可以直接复用原对象的对应资源,也可以按照业务需求重新初始化,deepcopy默认无法自动处理这类不可序列化的资源。
内容的提问来源于stack exchange,提问作者pguenther
相关产品推荐
相关产品推荐

