Python 深拷贝与浅拷贝
在 Python 中,当我们需要复制对象时,有两种方式:深拷贝和浅拷贝。深拷贝会创建一个新的对象,同时复制对象中的所有子对象,而浅拷贝仅复制对象的引用。在本文中,我们将详细讨论这两种拷贝方式,并提供一些代码示例。
浅拷贝
浅拷贝是指在内存中创建一个新的对象,该对象与原始对象具有相同的值。然而,原始对象和新对象共享相同的子对象。这意味着,如果我们改变原始对象中的子对象,新对象也会受到影响。浅拷贝可以通过使用切片操作符([:]
)或 copy()
方法来实现。
下面是使用切片操作符进行浅拷贝的示例代码:
original_list = [1, 2, [3, 4]]
shallow_copy = original_list[:]
我们可以通过修改原始列表中的子列表来验证浅拷贝的行为:
original_list[2].append(5)
print(original_list) # 输出 [1, 2, [3, 4, 5]]
print(shallow_copy) # 输出 [1, 2, [3, 4, 5]]
可以看到,当我们修改原始列表中的子列表时,浅拷贝副本也会受到影响。
深拷贝
与浅拷贝不同,深拷贝会创建一个全新的对象,并复制对象中的所有子对象。这意味着,原始对象和新对象是完全独立的,互不影响。在 Python 中,我们可以使用 copy.deepcopy()
方法来执行深拷贝操作。
下面是使用 copy.deepcopy()
方法进行深拷贝的示例代码:
import copy
original_list = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(original_list)
我们可以通过修改原始列表中的子列表来验证深拷贝的行为:
original_list[2].append(5)
print(original_list) # 输出 [1, 2, [3, 4, 5]]
print(deep_copy) # 输出 [1, 2, [3, 4]]
可以看到,当我们修改原始列表中的子列表时,深拷贝副本不受影响。
类图
下面是深拷贝和浅拷贝的类图示例:
classDiagram
class Object
class ShallowCopy
class DeepCopy
Object <|-- ShallowCopy
Object <|-- DeepCopy
在上面的类图中,Object
是所有对象的基类。ShallowCopy
和 DeepCopy
是两个派生类,用于表示浅拷贝和深拷贝。
走进源码
在 Python 中,浅拷贝和深拷贝的实现主要依赖于 copy
模块。下面是 copy
模块的部分源码:
def copy(x):
cls = type(x)
# 通过 __copy__ 魔法方法进行拷贝
copier = getattr(x, "__copy__", None)
if copier:
return copier()
# 创建一个新对象
if isinstance(x, _Array):
return x.copy()
copier = _copy_dispatch.get(cls)
if copier:
return copier(x)
# 如果对象是可迭代的,则创建一个新的迭代器对象
if issubclass(cls, type({}.keys())):
return cls(x)
# 创建一个空对象,并将原始对象的属性复制到新对象中
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error("un(shallow)copyable object of type %s" % cls)
return _reconstruct(x, rv, 0)
可以看到,拷