python动态类型

在python中,类型是在运行过程中自动决定的,而不是通过代码声明。这意味着没有必要事先声明变量。即,在python中,变量名没有类型,类型属于对象而不是变量名。从另一方面讲,对象知道自己的类型。每个对象都包含了一个头部信息,其中标记了这个对象的类型。


对象的垃圾收集

每当一个变量名被赋予了一个新的对象,之前的那个对象占用的空间就会被回收(如果它咩有被其他的变量名或对象所引用的话)。这种自动回收对象空间的技术称作垃圾收集。在内部,python是通过保持用每个对象中的计数器记录引用知道这个对象上的次数来完成这一功能的。一旦这个计数器被设置为零,这个对象的内存空间就会自动回收。


共享引用

>>> a = 3

>>> b = a

实际的效果就是:变量a和b都引用了相同的对象3(也就是说,指向了形同的内存空间)。这在python中称作是共享引用---多个变量名引用了同一个对象。

>>> a = 3

>>> b = a

>>> a = 'spam'

实际的效果是:变量b仍然引用了原来的对象3,变量a引用了新创建的对象'spam'

共享引用和在原处修改

有一些对象和类型确实会在实地改变对象。例如,在一个列表中对一个偏移进行赋值确实会改变这个列表对象,而不是生成一个新的列表对象。对于支持这种在原处修改的对象,共享引用时的确需要加倍的小心,因为对一个变量名的修改会影响其他的变量。

这种行为通常来说是你所想要的,应该了解它是如何运作的,让它按照预期去工作,这也是默认的。如果你不想要这样的现象发生,需要Python拷贝对象,而不是创建引用。有很多中拷贝一个列表的方法,包括内置列表函数以及标准库的copy模块。也许最常用的办法就是从头到尾的分片。

>>>L1 = [2,3,4]

>>>L2 = L1[:]

>>>L1[0] = 24

>>>L1

[24,3,4]

>>>L2

[2,3,4]

注意:这种分片技术不会应用在其他的可变的核心类型(字典,因为他们不是序列)上,对字典应该使用D.copy()方法。而且,注意标准库中的copy模块有一个通用的拷贝任意对象类型的调用,也有一个拷贝嵌套对象结构(例如,嵌套了列表的一个字典)的调用。

import copy

X = copy.copy(Y) #make a top-level "shallow" copy of any object Y

X = copy.deepcopy(Y) #make a deep copy of any object Y:copy all nested parts

共享引用和相等

>>>x=42

>>>x='shrubbery'

python缓存并复用了小的整数和小的字符串,这里的对象42也许并不像我们所说的被回收;相反地,它将可能仍被保存在一个系统表中,等待下一次你的代码生成另一个42来重复利用。尽管这样,大多数种类的对象都会在不再引用时马上回收。

由于python的引用模型,在python程序中有两种不同的方法去检查与否相等。“==操作符”,测试两个被引用对象是否有相同的值。“is操作符”检查对象的同一性,如果两个变量名精确的指向同一个对象,它返回true,所以这是一种更严格形式的相等测试。


对象被引用次数查询

python在sys模块中的getrefcount函数会返回对象的引用次数。

posted @ 2014-07-28 16:42  JerryShao  阅读(492)  评论(0编辑  收藏  举报