Python动态类型

静态类型与动态类型

动态、静态是指变量的绑定方式,静态语言在编译时绑定,动态语言可以在运行时随意绑定。Python属于动态类型。

强类型与弱类型

强、弱类型是说变量的类型在运算上下文中是否可以自动转换。Python属于强类型。

变量,对象和引用

在python中,类型是在运行过程中自动决定的,而不是通过代码声明。这意味着没有必要事先声明变量。

a=3解析的过程:

总之,变量在赋值的时候才创建,它可以引用任何类型的对象,并且必须在引用前赋值。

上面的代码的赋值操作:

如上图所示,变量和对象保存在内存的不同部分,它们通过连接相关联(图中箭头)。

具体的,在运行a=3后,变量a变成对象3的一个引用。在内部,变量事实上是到对象内存空间(通过运行常量表达式3创建)的一个指针。

以具体的术语来讲,

事实上,python并不是对创建的所有对象都会重新申请新的一块内存空间。作为一种优化,python会缓存不变的对象(如数值较小的数字,字符串,元组等)并对其进行复用。

类型属于对象,而不是变量

>>> a = 3
>>> a = 'viper'
>>> a = 1.333

变量a刚开始是整数,然后是字符串,最后是浮点数,但是这段代码可以运行。这是因为,在python中,情况很简单,变量名没有类型。上面的代码,我们只是把变量a修改为对不同对象的引用,从而让变量a引用了不同类型的对象而已。

共享引用

>>> a=3
>>> b=a

可以看到变量a,b引用了同一个对象。这时,让变量a引用另一个对象。

>>> a=3
>>> b=a
>>> a='viper'

a='viper'创建了一个新的对象'viper',并让变量a对这个新对象引用,而变量b仍然引用原来的对象3.所以这时变量b的值是3.

共享引用和在原处修改

有一些对象和操作确实会在原处改变对象,例如,在一个列表中对一个偏移赋值就会改变这个列表对象,而不是生成一个新的列表对象。对于这种可以在原处修改的对象,共享引用的时候要小心,因为对一个变量名的修改会影响其他和它引用同一对象的变量。

>>> L1 = [1,2,3]
>>> L2 = L1
>>> L1[0] = 33

这时变量L1,L2的值都会变成[33,2,3],这种行为通常不是我们想要的,但是这种行为是默认的,如果不想这种行为发生,就需要拷贝对象,而不是创建引用。

>>> L1 = [1,2,3]
>>> L2 = L1[:]
>>> L1[0] = 'viper'
>>> print(L2)# [1,2,3]

因为L2引用的是L1引用对象的一个拷贝,这里两个变量指向不同的内存区域。所以L1的改变不会影响L2.注意上面用到了分片,其他的有些可变的核心类型(如字典,集合)不能分片,这时就使用copy()方法。

共享对象和相等

由于python的引用模型,在python程序中有两种不同的方法检查是否相等。==is

== 检查两个被引用的对象是否拥有相同的值,这种方法被用作相等的检查。is会比较实现引用的指针,是检测共享引用的一种方法。如果变量的引用值相等,但是是不同的对象,那is就返回false.比如,

>>> L = [1, 2, 3]
>>> M = [1, 2, 3]    #M and L reference different objects
>>> L == M           #Same values
True
>>> L is M           #Different objects
False

变量M和L虽然值相同,但它们两个不同的对象,在不同的内存区域。另外,

>>> X = 42
>>> Y = 42
>>> X == Y
True
>>> X is Y
True

这个验证了前面说的Python会缓存不变的对象(如数值较小的数字,字符串,元组等)并对其进行复用。y=3只是让变量y引用已经创建的对象3.

转自:http://www.cnblogs.com/TheViper/p/4749800.html

-- EOF --
发表于: 2015-12-07 15:38
标签: Python