克隆对象
Python中的赋值语句不会创建对象的副本,只是将名称绑定到对象上。对于不可变对象也是如此。但为了处理可变对象或可变对象集合,需要一种方法来创建这些对象的“真实副本”或“克隆体”。从本质上讲,你有时候需要用到对象的副本,以便修改副本时不会改动本体。先来看如何复制Python的内置容器(collection)。Python的内置可变容器,如列表、字典和集合,调用对应的工厂函数就能完成复制:使用copy模块中的deepcopy函数创建深副本:
现在原对象和副本是完全独立的。复制过程中递归复制了xs,包括它的所有子对象。
By the way, copy.copy()函数会创建对象的浅副本。
在代码中,copy.copy()可以清楚地表明创建的是浅副本。但对于内置容器,只需要使用list、dict和set这样的工厂函数就能创建副本,这种方式更具Python特色。
复制任意对象
copy模块中的copy和deepcopy函数可以复制任意对象。
首先定义一个2D 点类:
由于点对象使用不可变类型(int)作为坐标,浅深复制之间并没有区别。下面来看一个更复杂的例子, 2D矩形类:
可以看到修改原对象的子对象,浅复制的副本相应发生变化。
而深复制则不会:
关键要点:
创建的浅副本不会克隆子对象,因此副本和原对象并不完全独立。
对象的深副本将递归克隆子对象。副本完全独立于原对象,但创建 深副本的速度比较慢,因为发生了递归。
使用copy模块可以复制任意对象(包括自定义对象)。