介绍
deepcopy是用来进行深层复制的, 但是在实际中可能遇到, 复制一个对象后, 某些属性没了, 因此看看源码, 顺便记录下来.
Python 版本: 3.6
copy模块位置: copy.py (Python的lib包里面)
deepcopy原理概括: deepcopy的逻辑要根据对象的不同发生变化, 比如float, int等, 直接拷贝一个就行了, 若是一个复杂的对象, 要将各个属性都要复制才行. deepcopy对象潜在问题有, 一是可能存在循环引用(比如对象的某个属性引用了自身), 二是如何构建新的对象作为对象的一个复制.
问题一的解决是通过一个memo参数实现的, 如果发现某个id对应的对象复制过了, 就不再复制了.
问题二的解决是通过对象的__reduce__
和__reduce_ex__
等函数, 得到对象的参数表示, 然后复制这个参数表示, 再通过_reconstruce
函数构建一个对象, 就得到了对象的一个deepcopy. 也可以通过__deepcopy__
函数自定义一个对象的复制逻辑.
源码注释
"""
deepcopy的主要逻辑在下面的函数.
deepcopy的文档: https://docs.python.org/3/library/copy.html
"""
def deepcopy(x, memo=None, _nil=[]):
"""Deep copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
"""
if memo is None:
memo = {
}
# memo 用于记录对象是否被复制过了, 可以防止对象出现循环引用导致无限复制的情景.
d = id(x)
y = memo.get(d, _nil)
if y is not _nil:
return y
cls = type(x)
copier = _deepcopy_dispatch.get(cls) # 一些内置的数据类型有特定的复制函数, 比如list等, 在copy.py中可以找到其定义.
if copier:
y = copier(x, memo)
else:
try:
issc =