Python动态类型:变量、对象和引用解析

Python动态类型:变量、对象和引用解析

1、变量、对象和引用 类型属于对象,而不是变量:变量名没有类型,对象才有类型,变量实质上是指向对象所在内存空间的指针,变量只是对对象的引用。 不同赋值,因为变量没有类型,所以实质上只是修改变量a为对不同类型的变量的引用。变量总是一个指向对象的指针,而不是可改变的内存区域的标签。给一个变量赋新值,并不是替换原始的对象,而是让这个变量去引用别的对象。通俗的讲就是一个变量被赋新值,只会影响这个变量,而不会影响其共享对象的变量。 >>> a=3 >>> a 3 2、对象的垃圾收集 对象包括两个头部信息:类型标志位和引用计数器。 类型标志位指对象的类型,如int,str 引用计数器指当前引用该对象的数目,当数目为0时,对象的空间被自动回收。 >>> a=abc >>> a abc >>> a=3.2 -->abc被回收 >>> a 3.2 >>> 3、共享引用(共享对象)

两个变量同时引用3这个对象 >>> a=3 >>> b=a >>> a 3 >>> b 3 >>> 4、共享引用和相等 == 比较两个被引用的对象是否具有相同的值 is 比较实现引用的指针是否相同,即是否引用同一对象,是否为共享引用。 如1: >>> a=[1,2] >>> b=a >>> a==b True >>> a is b True >>> 如2: >>> a=[1,2] >>> b=[1,2] >>> a is b False >>> a==b True >>> 5、共享引用和在原位置修改 引用了一个在原位置上发生改变的对象,共享引用也同样改变。 >>> l1=[1,2,3,4] >>> l2=l1 >>> l1 [1, 2, 3, 4] >>> l2 [1, 2, 3, 4] 如直接给l1赋新值,则l2不变 如 l1=24 l2仍为[1,2,3,4] >>> l1=24 >>> l1 24 >>> l2 [1, 2, 3, 4] >>> 如改变l2所引用对象的一个元素,这类修改会在原位置上覆盖列表对象的某部分值。则l2改变,尽管实质上并未改变l1的值,l1引用了一个在原位置上发生改变的对象,也同样改变。 >>> l1=[1,2,3,4] >>> l2=l1 >>> l1 [1, 2, 3, 4] >>> l2 [1, 2, 3, 4] >>> l2[2]=888 >>> l1 [1, 2, 888, 4] >>> l2 [1, 2, 888, 4] >>> 6、使用Python复制而不是创建引用可以避免原位置修改问题 1)、列表分片 >>> l1=[1,2,3,4] >>> l2=l1[:] >>> l1 [1, 2, 3, 4] >>> l2 [1, 2, 3, 4] >>> l2[2]=888 >>> l1 [1, 2, 3, 4] >>> l2 [1, 2, 888, 4] >>> 2)、复制和深度复制 >>> l1=[1,2,3,4] >>> import copy >>> l2=copy.copy(l1) >>> l1 [1, 2, 3, 4] >>> l2 [1, 2, 3, 4] >>> l1[1]=666 >>> l1 [1, 666, 3, 4] >>> l2 [1, 2, 3, 4] >>> >>> l2=copy.deepcopy(l1) >>> l1 [1, 666, 3, 4] >>> l2 [1, 666, 3, 4] >>> l1[1]=2 >>> l1 [1, 2, 3, 4] >>> l2 [1, 666, 3, 4] >>>

经验分享 程序员 微信小程序 职场和发展