本篇介绍下python中的深拷贝和浅拷贝,主要从基本类型、类、不可变类型等方面进行介绍。
1.介绍拷贝之前首先应该明白is和==的区别,即is表示同一个对象,==比较的是值
>>> a = 1000 >>> b = 1000 >>> a == b True >>> a is b False
class Person(object): def __init__(self, name): self.name = name p1 = Person("lingling") p2 = Person("lingling") print(p1 is p2) # False print(p1 == p2) # False
总结:因为p1和p2不是同一个对象,所以返回False,==是比较的值,因为这是自定义的类,python解释器并不知道比较的规则,所以使用默认的比较规则,即调用这个对象所属类中的魔法方法__eq__(),因为Person类并没有重写这个方法,所以默认调用object中的__eq__()方法,object中的__eq__()方法,默认使用了is的比较值。
def __eq__(self, *args, **kwargs): # real signature unknown """ Return self==value. """ pass
重写__eq__之后
class Person(object): def __init__(self, name): self.name = name def __eq__(self, other): return self.name == other.name p1 = Person("lingling") p2 = Person("lingling") print(p1 is p2) # False print(p1 == p2) # True
2.基本类型
# 浅拷贝 In [1]: import copy In [2]: a=[10,20] In [3]: b=[30,40] In [4]: c=[a,b] In [5]: d=copy.copy(c) In [6]: c is d Out[6]: False In [7]: c Out[7]: [[10, 20], [30, 40]] In [8]: d Out[8]: [[10, 20], [30, 40]] In [9]: a.append(50) In [10]: c Out[10]: [[10, 20, 50], [30, 40]] In [11]: d Out[11]: [[10, 20, 50], [30, 40]] In [12]: c is d Out[12]: False #深拷贝 In [13]: a=[10,20] In [14]: b=[10,20] In [15]: c=[a,b] In [16]: d=copy.deepcopy(c) In [17]: c is d Out[17]: False In [18]: a.append(50) In [19]: c Out[19]: [[10, 20, 50], [10, 20]] In [20]: d Out[20]: [[10, 20], [10, 20]] In [21]: c is d Out[21]: False
总结:浅拷贝即只复制第一层数据,更深层的引用不管,深拷贝,是最深层值的拷贝。
3.不可变类型
In [22]: a=(1,2) In [23]: b=copy.copy(a) In [24]: a is b Out[24]: True In [25]: b=copy.deepcopy(a) In [26]: a is b Out[26]: True In [27]: a=[10,20] In [28]: b=[30,40] In [29]: c=(a,b) In [30]: d=copy.copy(c) In [31]: c is d Out[31]: True In [32]: d=copy.deepcopy(c) In [33]: c is d Out[33]: False
总结:对于元组这种不可变类型,是不能修改的,所以Python为了省存储空间,对于不可变类型,内存中始终维护着一份数据。