您的位置:首页 > 编程语言 > Python开发

python语法31[引用和拷贝]

2013-03-24 19:29 253 查看
If an object’s value can be modified, the object is said to be mutable. If the value cannot be modified,the object is said to be immutable.

mutable 可变类型,例如 list,set,自定义类型(等价于C#中的引用类型);

immutable 不可变类型,例如string,numbers等(等价于C#中的值类型);

一 引用和拷贝(references and copies)

当程序中使用=赋值操作符时,例如a=b,

对于不可变的对象,a作为b的一个拷贝被创建,a和b将指向不同的内存地址,a和b相互独立。

def TestCopy():
a = 10
b = a
a =20
print (b) #b still is 10

但是对于可变的对象,a作为b的一个引用被创建,a和b的元素公用相同的内存地址,a和b的元素共享。

def TestRef():
a=[1,2,3,4]
b=a #b is a reference to a
print (b is a) # True
b[2] = -100 #change an element in b
print (a) # a also changed to [1,2,-100,4]

二 深拷贝和浅拷贝(shallow copy and deep copy)

为了避免可变对象指向同一个对象,必须创建一个新的拷贝,而不是引用。

在python中可以对容器对象(例如lists和dictionaries)使用两种拷贝:浅拷贝和深拷贝。

浅拷贝创建一个新的对象,但是使用原来对象的元素的引用(如果是不变类型,相当于是拷贝)来填充新对象。可以使用copy.copy()来实现浅拷贝。

def TestShallowCopy():
a = [ 1, 2, [3,4] ]
b = list(a) # create a shallow copy of a
print (b is a) #False
b.append(100) #append element to b
print (b)
print (a) # a is unchanged
b[2][0] = -100 # modify an element inside b
print (b)
print (a) # a is changed
在这个例子中,a和b共享相同的可变元素。所以修改其中一个list对象中的元素,另一个list对象也会被修改。

深拷贝创建一个新的对象,同时递归地拷贝对象所包含的所有的元素。可以使用copy.deepcopy()来实现深拷贝。

def TestDeepCopy():
import copy
a = [1, 2, [3, 4]]
b = copy.deepcopy(a)
b[2][0] = -100
print (b) # b is changed
print (a) # a is unchanged
在这个例子中,a和b是对立的list对象,且他们的元素也相互独立。

三 引用计数和垃圾回收

python中的所有的对象都是引用计数的,一个对象赋值或加入容器时,它的引用计数就会自增,当使用del时或变量赋值为其他值时,引用计数就会自减,当引用计数为0时,python的垃圾回收器就会回收该变量。

def TestGarbageCollection():
import sys
print(sys.getrefcount(37))
a = 37 # Creates an object with value 37
print(sys.getrefcount(37))
b = a # Increases reference count on 37
print(sys.getrefcount(37))
c = []
c.append(b) # Increases reference count on 37
print(sys.getrefcount(37))
del a # Decrease reference count of 37
print(sys.getrefcount(37))
b = 42 # Decrease reference count of 37
print(sys.getrefcount(37))
c[0] = 2.0 # Decrease reference count of 37
print(sys.getrefcount(37))

TestGarbageCollection()

运行结果为:

11
12
13
14
13
12
11

为啥一上来就有11个引用了呢?谁知道?

参考:Python ESSENTIAL REFERENCE (Fourth Edition)的第三章 Types and Objects -> References and Copies

完!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: