Understanding References

    Python将数据放在对象中,变量只不过是对象的一个引用;变量为内存中某个点取了一个名字而已。所有对象都有一个唯一的身份号、类型以及值。

1. Object identity

    因为是对象,而不是变量,有一个数据类型,所以一个变量在某个时候可以引用一个list,而在另一个时候可以引用一个浮点数。一个对象它的类型永远无法改变,但对于lists以及其他一些mutable类型,它们的值是可以改变的。

    Python提供了 id(obj) 这样一个函数,它返回的就是对象的identity,也就是对象在内存中的地址。

>>> shoppingList = [‘candy’,’cookies’,’ice cream’]

>>> id(shoppingList)

17611492

>>> id(5)

3114676

    操作符 is 作用是比较两个对象的identity,判断它们是否是同一个对象。

>>> junkFood = shoppingList # Both reference the same object

>>> junkFood is shoppingList

1

>>> yummyStuff = [‘candy’,’cookies’,’ice cream’]

>>> junkFood is not yummyStuff # Different identity, but...

1

>>> junkFood == yummyStuff # ...same value

1

    因为变量仅仅是引用某个对象,修改了某个mutable对象的值后,所有引用该对象的变量都可以看到该变化:

>>> a = [1,2,3,4]

>>> b = a

>>> a[2] = 5

>>> b

[1, 2, 5, 4]

>>> a = 6

>>> b = a     # Reference the same object for now.

>>> b

6

>>> a = a + 1 # Python creates a new object to hold (a+1)

>>> b         # so b still references the original object.

6

2. Counting references

    每个对象都有一个引用计数,指明有多少变量在引用该对象。当你将一个变量附到一个对象上,或者当把一个对象放到一个list或其他容器中时,引用计数就会增加。当销毁、reassign、或从容器中移除一个对象,引用计数就会减少。当引用计数到达 0,Python的垃圾收集器就会销毁该对象,重新开垦这块被使用的内存。

    sys.getrefcount(obj) 函数返回指定对象的引用计数。

====新特性

从2.0版开始,Python现在还收集只带循环引用的对象。例如,

a = []; b = []

a.append(b); b.append(a)

a = 5; b = 10 # Reassign both variables to different objects.

The two list objects still have a reference count of 1 because each is a member of

the other’s list. Python now recognizes such cases and reclaims the memory used

by the list objects.

========================================================================================

    要记住,del语句删除的是变量,而不是对象,尽管如果一个你要删除的变量是一个对象的唯一引用,随后Python也会删除该对象。

>>> a = [1,2,3]

>>> b = a # List object has 2 references now

>>> del a # Back to 1 reference

>>> b

[1, 2, 3]

你也可以创建 weak references,或者那些不会影响一个对象的引用计数的引用。

猜你喜欢

转载自zsjg13.iteye.com/blog/2230309