这里有新鲜出炉的 Python 多线程编程, 程序狗速度看过来!
Python 编程语言
Python 是一种面向对象, 解释型计算机程序设计语言, 由 Guido van Rossum 于 1989 年底发明, 第一个公开发行版发行于 1991 年. Python 语法简洁而清晰, 具有丰富和强大的类库. 它常被昵称为胶水语言, 它能够把用其他语言制作的各种模块 (尤其是 C/C++) 很轻松地联结在一起.
这篇文章主要介绍了 Python 中对象的引用与复制代码示例, 具有一定借鉴价值, 需要的朋友可以了解下.
可以说 Python 没有赋值, 只有引用. 你这样相当于创建了一个引用自身的结构, 所以导致了无限循环. 为了理解这个问题, 有个基本概念需要搞清楚.
Python 没有「变量」, 我们平时所说的变量其实只是「标签」, 是引用.
python 中,"a=b" 表示的是对象 a 引用对象 b, 对象 a 本身没有单独分配内存空间 (重要: 不是复制!), 它指向计算机中存储对象 b 的内存. 因此, 要想将一个对象复制为另一个对象, 不能简单地用等号操作, 要使用其它的方法. 如序列类的对象是 (列表, 元组) 要使用切片操作符 (即':') 来做复制.
在 python 进行像 b = a 这样的赋值时, 只会创建一个对 a 的新引用, 使 a 的引用计数加 1, 而不会创建新的对象:
>>> a = 'xyz'
>>> import sys
>>> sys.getrefcount(a)
3
>>> b = a
>>> sys.getrefcount(b)
4
>>> id(a)
88292288L
>>> id(b)
88292288L
这样, 当引用的对象是可变对象的时候 (列表, 字典, 可变集合等), 会产生意料之外的行为:
>>> a = [1, 2, 3, 4]
>>> b = a
>>> b.append(5)
>>> a
[1, 2, 3, 4, 5]
因为 a 和 b 引用的是同一对象, 改变其中一个, 另外一个也会随之改变. 当我们想建立一个副本而不是引用时, 可以复制对象.
复制对象一般使用 copy 模块:
>>> a = [1, 2, 3, 4]
>>> import copy
>>> b = copy.copy(a)
>>> b.append(5)
>>> b
[1, 2, 3, 4, 5]
>>> a
[1, 2, 3, 4]
这样就可以了, 但这种复制是一种浅复制, 复制的新对象中包含的是对原始对象中的项的引用, 如果对象的项为可变对象, 也会产生不可控行为:
>>> a = [1, [1, 2]]
>>> b = copy.copy(a)
>>> b[1].append(3)
>>> b
[1, [1, 2, 3]]
>>> a
[1, [1, 2, 3]]
这时候就要使用深复制了. 深复制将创建一个新对象, 并递归地复制它所包含的所有对象:
>>> a = [1, [1, 2]]
>>> b = copy.deepcopy(a)
>>> b[1].append(3)
>>> b
[1, [1, 2, 3]]
>>> a
[1, [1, 2]]
对于不可改变的对象而言 (字符串, 数字, 元组) 等, 没有必要拷贝, 因为它们是不可改变的, 不用担心会不经意间改动了它们. 拷贝操作也只会得到原对象:
>>> a = (1, 2, 3)
>>> b = copy.copy(a)
>>> a is b
True
对于可变对象来 (列表, 字典, 可变集合) 来说, 可以分别使用内置函数 list(),dict(),set() 来进行浅复制, 速度是比使用 copy 模块快的.
列表也可以使用切片进行浅复制:
>>> a = [1, 2, 3, 4]
>>> b = a[:]
>>> a is b
False
>>> b
[1, 2, 3, 4]
对序列数据类型 (字符串, 列表, 元组) 进行 * 操作时, 也仅仅是复制了对象中项的引用, 如果使用 * 创建一个多维列表:
>>> a = [1, 2, 3]
>>> b = [a]
>>> c = b * 3
>>> a.append(4)
>>> c
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
最好是在列表推导中使用浅复制来创建多维列表, 可以避免隐式的引用共享:
>>> a = [1, 2, 3]
>>> c = [list(a) for i in range(3)]
>>> a.append(4)
>>> c
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
总结
以上就是本文关于 Python 中对象的引用与复制代码示例的全部内容, 希望对大家有所帮助. 感兴趣的朋友可以继续参阅本站其他相关专题, 如有不足之处, 欢迎留言指出.
来源: http://www.phperz.com/article/18/0128/361499.html