一、变量、对象、引用及其关系:
从举例说明Python创建变量的步骤:a = 3;
Python将会执行3个不同的步骤去完成这个请求。这些步骤反应了Python语言中所有赋值的操作:
1、创建一个对象来代表值3;
2、创建一个变量a,如果它还没被创建的话;
3、讲变量与新的对象3连接。
实际效果是如图所示的在一个Python的内部结构。变量和对象在内存中的不同部分,并通过连接相关联(这个连接在图中显示为一个箭头)。变量总是连接到对象,并且绝不会连接到其他变量上,但是更大的对象可能连接到其他对象(例如,一个列表对象能够连接到它所包含的对象)。变量名和对象,在运行a = 3后,变量a变成对象3的一个引用。在内部,变量事实上是到对象内存空间(通过运行常量表达式3而创建)的一个指针。
在Python中从变量到对象的连接称作引用。也就是说,引用是一种关系,以内存中的指针的形式实现。一旦变量被使用(也就是说被引用),Python自动跟随这个变量到对象的连接。以具体的术语来讲:
· 变量是一个系统表的元素,拥有指向对象的连接的空间。
· 对象是被分配的一块内存,有足够的空间去表现他们所代表的值。
· 引用是自动形成的从变量到对象的指针。
在脚本中,每一个通过运行一个表达式生成一个新的值,Python都创建了一个对象(一个内存)去表现这个值。从逻辑的角度看,这工作起来就像每一个表达式结构的值都是一个不同的对象,而每一个对象都是不同的内存。
从技术上讲,对象有更复杂的结构而不仅仅是有足够的空间去表现它的值那么简单。每一个对象都有两个标准的头部信息:一个类型标识符去标识这个对象的类型,以及一个引用计数器,用来决定是不是可以回收这个对象。
变量没有类型,类型属于对象,而不是变量名。
每当一个变量名被赋予了一个新的对象,之前的那个对象占用的空间就会被回收(如果它没有被其他变量名所引用的话)。这种自动回收对象空间的技术称作垃圾收集。在内部,Python是通过保持用每个对象中计数器记录引用到这个对象上的次数来完成这一功能的。一旦(并精确在同一时间)这个计数器被设置为零,这个对象的内存空间就会自动回收。
二、共享引用
>>> a = 3
>>> b = a
输入这两行语句后,生成如图结果:
第二行会使Python创建变量b。使用的是变量a,并且它在这里没有被赋值,所以它被替换成其引用的对象3,从而b也成为这个对象的一个引用。实际的效果就是变量a和变量b都引用了相同的对象(也就是说,指向了相同的内存空间)。这在Python中称为共享引用——多个变量名引用了同一个变量。
给一个变量赋一个新的值,并不是替换了原始的对象,而是让这个变量去引用另一个对象。
注:分片是对对象的拷贝
共享引用和相等:
Eg:
>>> L = [1, 2, 3]
>>> M = L
>>> L == M
True
>>> L is M
True
这里的第一种技术“==操作符”,测试两个被引用对象是否有相同的值。这种方法往往在Python中用作相等的检查。第二种方法“is操作符”,是在检查对象的同一性。如果两个变量名精确地指向同一个对象,它会返回True,所以这是一种更严格形式的相等测试。
实际上,is只是比较实现引用的指针,所以如果必要的话是代码中检测共享引用的一种办法。如果变量名引用值相等,但为不同对象,它的返回值是False。
Eg:
>>> L = [1, 2, 3]
>>> M = [1, 2, 3]
>>> L == M
True
>>> L is M
False
参考文献:《Python学习手册 第三版》