edcf 发表于 2015-12-1 14:27:58

《python学习手册》笔记--动态类型

  转载请注明:TheViper http://www.cnblogs.com/TheViper
  变量,对象和引用
  在python中,类型是在运行过程中自动决定的,而不是通过代码声明。这意味着没有必要事先声明变量。
  a=3解析的过程:


[*]变量创建:这里的变量a,当代码第一次给它赋值时就创建了它,之后的赋值将会已创建的变量的值。
[*]变量类型:变量永远不会有任何和它关联的类型信息或约束。类型的概念存在于对象中而不是变量。变量原本是通用的,它只是在一个特定的时间点,简单的引用了一个特定的对象而已。
[*]变量使用:当变量出现在表达式中,它马上被当前引用的对象所替代,无论这个对象是什么类型。注意,所有变量必须在其使用前明确的赋值。
  总之,变量在赋值的时候才创建,它可以引用任何类型的对象,并且必须在引用前赋值。
  上面的代码的赋值操作:


[*]创建一个对象(这里是数字)代表值3.
[*]创建一个变量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=
L2=L1
L1=33
  这时变量L1,L2的值都会变成.
  这种行为通常不是我们想要的,但是这种行为是默认的,如果不想这种行为发生,就需要拷贝对象,而不是创建引用。



L1=
L2=L1[:]
L1='viper'
print(L2)#
  因为L2引用的是L1引用对象的一个拷贝,这里两个变量指向不同的内存区域。所以L1的改变不会影响L2.
  注意上面用到了分片,其他的有些可变的核心类型(如字典,集合)不能分片,这时就使用copy()方法。
  共享对象和相等
  由于python的引用模型,在python程序中有两种不同的方法检查是否相等。==和is
  ==检查两个被引用的对象是否拥有相同的值,这种方法被用作相等的检查。
  is会比较实现引用的指针,是检测共享引用的一种方法。如果变量的引用值相等,但是是不同的对象,那is就返回false.比如,

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

  这个验证了前面说的 python会缓存不变的对象(如数值较小的数字,字符串,元组等)并对其进行复用。y=3只是让变量y引用已经创建的对象3.
页: [1]
查看完整版本: 《python学习手册》笔记--动态类型