python 引用和对象理解
2017-03-12 13:11
411 查看
python 引用和对象理解
【自己总结】,python中的变量是实际对象的引用,[JavaScript中的变量可以类似理解!!!]1,
a = xx(xx可以是可变或不可变类型)
b= xx
则id(a) != id(b)。即虽然a和b都指向对象xx,但实际上两个xx对象并不是同一个,两者完全独立。这里有一点要说明,某些整数和某些字符串会出现id(a)==id(b)的情况,这是python用的一种缓存技术,因为这些整数和字符串很常用!
2,
a = xx(xx可以是可变或不可变类型)
b= a(显式指定b指向a指向的对象)
则id(a) == id(b)。
3,
a = xx(xx为不可变类型或不可变类型)
b = a
此时xx的引用有两个即a和b,若再次对b赋值b=yy则xx的引用b会被删除,而b现在是yy引用。
4,
对于不可变类型,如数字,字符串,元组,
a= xx(xx为不可变类型)
"更新"a的值,a=yy,则实际上是新创建了一个yy对象,引用a重新指向yy。而旧的xx对象被抛弃(垃圾回收)。所以实际上不可变类型的值是不可更新的,更新实际上是新建!
但是对于可变类型,如列表,字典,
a=xx(xx为可变类型,如列表[1,2,3])
更新a的值,a[0]=4,则引用a依然指向原来的对象xx。所以可变类型的值是可更新的。
今天浏览博客的时候看到这么一句话: python中变量名和对象是分离的;最开始的时候是看到这句话的时候没有反应过来。决定具体搞清楚一下python中变量与对象之间的细节。(其实我感觉应该说 引用和对象分离 更为贴切)
从最开始的变量开始思考:
在python中,如果要使用一个变量,不需要提前进行声明,只需要在用的时候,给这个变量赋值即可 (这个和C语言等静态类型语言不同,和python为动态类型有关)。
举第一个栗子:
a = 1
这是一个简单的赋值语句,整数 1 为一个对象,a 是一个引用,利用赋值语句,引用a指向了对象1;这边形象比喻一下:这个过程就相当于“放风筝”,变量a就是你手里面的“线”,python就跟那根“线”一样,通过引用来接触和拴住天空中的风筝——对象。
你可以通过python的内置函数 id() 来查看对象的身份(identity),这个所谓的身份其实就是 对象 的内存地址:
注:
python一切皆对象的理念,所以函数也是一个对象,因此可以使用 id() 函数的__doc__方法来查看这个函数的具体描述:
第二个栗子:
a = 2
a = 'banana'
利用上面第一个栗子用到的 id()函数:
第二个语句中,内存中建立了一个字符串对象‘banana’,通过赋值 将 引用a 指向了 ‘banana’,同时,对象1不在有引用指向它,它会被python的内存处理机制给当我垃圾回收,释放内存。
第三个栗子:
a = 3
b = 3
通过函数查看 变量a 和 变量b的引用情况:
第四个栗子:
1. a = 4
2. b = a(这里就是让引用b指向引用a指向的那个对象)
3. a = a + 2
通过函数查看引用情况:
当执行到第2步的时候,查看一下 a 和 b 的引用:
接下来指向第3步:
第五个栗子(这个栗子会涉及到 python中的 可变数据类型 和 不可变数据类型):
开始这个栗子之前,请记得注意到 第四个栗子的不同之处。
1. L1 = [1, 2, 3]
2. L2 = L1
3. L1[0] = 10
通过函数查看引用情况:
当执行第1步 和 第二步 的时候,查看一下 L1 和 L2 的引用情况:
接下来,继续执行第3步:
在该情况下,我们不再对L1这一引用赋值,而是对L1所指向的表的元素赋值。结果是,L2也同时发生变化。
原因何在呢?因为L1,L2的指向没有发生变化,依然指向那个表。表实际上是包含了多个引用的对象(每个引用是一个元素,比如L1[0],L1[1]..., 每个引用指向一个对象,比如1,2,3), 。而L1[0] = 10这一赋值操作,并不是改变L1的指向,而是对L1[0], 也就是表对象的一部份(一个元素),进行操作,所以所有指向该对象的引用都受到影响。
(与之形成对比的是,我们之前的赋值操作都没有对对象自身发生作用,只是改变引用指向。)
列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。
而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)。
我们之前学的元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.
is关键字:
当然,我们也可以要想知道是否指向同一个对象,我们可以使用 python的 is 关键词,is用于判断两个引用所指的对象是否相同。
就像上述第四个栗子 当进行到 第1步 和 第2步 的时候:
突然想到,对于python 的 深拷贝 和 浅拷贝 的理解,也是可以根据这个进行验证,可以通过第五个栗子进行辅助理解。
相关文章推荐
- python 引用和对象理解
- Python中的可变,不可变对象;值类型,引用类型;浅拷贝,深拷贝理解
- python 引用和对象理解
- Python中对象的理解:引用和赋值
- python 引用和对象理解(转)
- 【Python】引用和对象的理解
- python 引用和对象理解
- python 引用和对象理解
- 弱引用的用途:在底层C++对象被上层python脚本对象使用时(转)
- 一道理解c#中对象(引用类型)相互赋值和方法覆盖(overriding)的题目
- python 引用,拷贝,对象回收,弱引用
- 黑马程序员-Java_另类理解多态AND理解父类引用指向子类对象的方式
- python函数是引用传递(对可变对象而言)
- python类中显示重写__del__方法引起循环引用的对象无法释放,一种循环引用的检测方法
- php中引用&的真正理解-变量引用、函数引用、对象引用
- Python中的对象和动态性 [菜鸟的理解,高手莫入]
- python list中引用其它对象
- Java 中深层理解父类引用指向子类对象
- Python 初体验之 对象的引用和拷贝
- C#里的父类对象引用子类实例的理解