Python的对象拷贝

作者: 大蟒传奇 | 来源:发表于2017-03-05 23:11 被阅读284次

对象拷贝

在面向对象编程中,复制一个现有对象的副本,被称为对象拷贝。生成的对象被称之为对象副本。
拷贝是基本的操作,但是在实际操作过程中会有一些需要注意的地方。有多种方法来拷贝对象,最常见的是通过拷贝构造函数或者克隆函数。拷贝的主要目的是对副本做出修改、移动,或者是保留当前值。
如果不需要实现以上目的,则创建对原始数据的引用是更加高效的选择。

Python的对象拷贝

在Python中,赋值语句总是建立对象的引用,看下面的一段代码

>>> a = [1,2,3]
>>> b = a
>>> print(id(a), id(b))
(4420030688, 4420030688)

会发现b = a操作后,ab指向了同一块地址。

上面例子中,ab都是可变对象(list)的,对b的修改,同样可会影响到a,如下

>>> b.append(3)
>>> a
[1, 2, 3, 3]

那么对于可变的数据的副本,或者包含了可变对象的数据的副本,如何在不改变原数据的情况下操作副本呢?这里就要用到内置的copy模块了。

浅拷贝

浅拷贝

在浅拷贝中,会将原对象中所有字段复制给对象副本。如果某个字段是某个对象的引用(比如,一串内存地址),那么被拷贝的是这个引用,指向元数据中该字段指向的对象;如果字段是基本类型,则复制这个字段的值。

在Python这样万物皆是对象的语言中,使用浅拷贝后,对象副本中字段和原始数据中字段都会指向同一个对象,这样的情况下,引用的对象被共享,因此,如果这些对象中的一个被修改,则改变在另外一个中可见。浅拷贝很简单,可以通过简单的完全复制位来实现,所以开销也很小。

比如下面的例子。

>>> a = [[1,2,3], [1,2], [1]]
>>> id(a), id(a[0]), id(a[1]), id(a[2])
(4420406880, 4420406448, 4420406808, 4420406304)
>>> b = copy.copy(a)
>>> id(b), id(b[0]), id(b[1]), id(b[2])
(4420423760, 4420406448, 4420406808, 4420406304)

深拷贝

深拷贝

另一种方法是深拷贝,这意味着原对象中的字段被解引用。和浅拷贝不同,引用不再被拷贝,而是会为引用的值创建新的对象。也就是说对于副本的改变不会影响到原始数据。copy模块中的deepcopy函数可以实现这一点。

>>> import copy
>>> l1 = [2, 3, 4, [3, 5]]
>>> l2 = copy.deepcopy(l1)
>>> l1, l2
([2, 3, 4, [3, 5]], [2, 3, 4, [3, 5]])
>>> l2[3].append(6)
>>> l2.append(7)
>>> l1, l2
([2, 3, 4, [3, 5]], [2, 3, 4, [3, 5, 6], 7])

总结

Python中copy模块通过copy()deepcopy()函数来分别提供浅拷贝和深拷贝功能。程序员可以通过在对象中定义__copy__()__deepcopy()__方法来修改模块默认的实现。

相关文章

  • Python浅拷贝与深拷贝

    Python浅拷贝与深拷贝 一、可变对象与不可变对象 见Python变量 二、copy模块 对象拷贝是指在内存中创...

  • python 深拷贝与浅拷贝的区别

    python中浅拷贝和深拷贝的区别如下: copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。 ...

  • python 深拷贝与浅拷贝的区别

    python中浅拷贝和深拷贝的区别如下: 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对...

  • python 深拷贝与浅拷贝的区别

    python中浅拷贝和深拷贝的区别如下: 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对...

  • Day5 深拷贝和浅拷贝

    python的复制,深拷贝和浅拷贝 在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一...

  • python必知必会11

    Python 里面如何拷贝一个对象? 直接赋值:其实就是对象的引用(别名)。 浅拷贝 (shallow copy)...

  • 简介深浅拷贝

    深浅拷贝 python 直接赋值,浅拷贝和深拷贝 直接赋值 其实就是对象的引用 (可以理解成浅拷贝) 浅拷贝: 拷...

  • python中copy和deepcopy有什么区别?

    python中copy和deepcopy有什么区别? copy仅拷贝对象本身,而不对中的子对象进行拷贝,故对子对象...

  • Python 对象拷贝

    Python 赋值只是进行对象的引用。如果拷贝一个对象,则需要使用copy模块。 copy.copy() 进行浅拷...

  • 拷贝Python对象

    赋值 Python中对象的赋值是简单的对象引用(可以把这个对象看成一个盒子,赋值是给这个盒子上贴不同的标签,指向的...

网友评论

    本文标题:Python的对象拷贝

    本文链接:https://www.haomeiwen.com/subject/skfygttx.html