如果面试的时候 你说你对python编程精通,大概率会被问到深浅拷贝
面试官:说说深浅拷贝吧 !
我:好的,那我们就来说说深浅拷贝吧
先来看看官方文档
NAME
copy - Generic (shallow and deep) copying operations.DESCRIPTION
Interface summary:import copy x = copy.copy(y) # make a shallow copy of y x = copy.deepcopy(y) # make a deep copy of y For module specific errors, copy.Error is raised. The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances). - A shallow copy constructs a new compound object and then (to the extent possible) inserts *the same objects* into it that the original contains. - A deep copy constructs a new compound object and then, recursively, inserts *copies* into it of the objects found in the original. Two problems often exist with deep copy operations that don't exist with shallow copy operations: a) recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop b) because deep copy copies *everything* it may copy too much, e.g. administrative data structures that should be shared even between copies Python's deep copy operation avoids these problems by: a) keeping a table of objects already copied during the current copying pass b) letting user-defined classes override the copying operation or the set of components copied This version does not copy types like module, class, function, method, nor stack trace, stack frame, nor file, socket, window, nor array, nor any similar types. Classes can use the same interfaces to control copying that they use to control pickling: they can define methods called __getinitargs__(), __getstate__() and __setstate__(). See the documentation for module "pickle" for information on these methods.
FUNCTIONS
copy(x)
Shallow copy operation on arbitrary Python objects.See the module's __doc__ string for more info. deepcopy(x, memo=None, _nil=[]) Deep copy operation on arbitrary Python objects. See the module's __doc__ string for more info.
英语好的可以退下了,我们用程序来直观的看看
先重复三遍,
浅拷贝 :只拷贝父对象,不拷贝子对象
浅拷贝 :只拷贝父对象,不拷贝子对象
浅拷贝 :只拷贝父对象,不拷贝子对象
原对象 a
浅拷贝对象 b
>>> a = [1,[2,3]]
>>> import copy
>>> b = copy.copy(a)
>>> b
[1, [2, 3]]
>>> a.append(10)
>>> a
[1, [2, 3], 10]
>>> b
[1, [2, 3]]
>>> id(a)
1197578901256
>>> id(b)
1197579044168
这里的原对象a 和 浅拷贝对象的id相同,也可以理解为指向同一个内存地址
浅拷贝 :只拷贝父对象,不拷贝子对象
浅拷贝 :只拷贝父对象,不拷贝子对象
浅拷贝 :只拷贝父对象,不拷贝子对象
那么也就是说,对a的子对象的修改,同样对b也会生效。
>>> a
[1, [2, 3]]
>>> a[1]
[2, 3]
>>> a[1].append("a")
>>> a
[1, [2, 3, 'a'], 10]
>>> b
[1, [2, 3, 'a']]
>>> id(a[1])
1197578902216
>>> id(b[1])
1197578902216
总结:浅拷贝 :只拷贝父对象,不拷贝子对象
再来看看深拷贝
重复三遍
深拷贝 :拷贝父对象和子对象
深拷贝 :拷贝父对象和子对象
深拷贝 :拷贝父对象和子对象
原对象 a
深拷贝对象 c
>>> a
[1, [2, 3, 'a'], 10]
>>> c = copy.deepcopy(a)
>>> id(a)
1197578901256
>>> id(c)
1197579034312
>>> a.append(888)
>>> a
[1, [2, 3, 'a'], 10, 888]
>>> c
[1, [2, 3, 'a'], 10]
>>>
>>>
深拷贝下对a的子对象修改,c会变么?
要分两种情况,一种是子对象是可变对象,另一种子对象是不可变对象
答案是:
子对象是可变对象时,修改a的子对象,是值拷贝
子对象是不可变对象时,修改a的子对象,而是引用拷贝
子对象是可变对象时,修改a的子对象,是值拷贝
>>> a[1].append("ff")
>>> a
[1, [2, 3, 'a', 'ff'], 10, 888]
>>> c
[1, [2, 3, 'a'], 10]
>>> id(a[1])
1197578902216
>>> id(c[1])
1197579033992
子对象是不可变对象时,修改a的子对象,而是引用拷贝(值和内存地址都一样叫引用拷贝)
>>> a = [2,(1,2)]
>>> c = copy.deepcopy(a)
>>> c
[2, (1, 2)]
>>>
>>>
>>> id(a[1])
1197577642696
>>> id(c[1])
1197577642696