python的深浅拷贝

如果面试的时候 你说你对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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值