给妹子讲python-S01E10动态类型与共享引用-阿里云开发者社区

开发者社区> Python爱好者> 正文

给妹子讲python-S01E10动态类型与共享引用

简介:

【妹子说】这段时间以来,我一直有个疑问,C语言中可以看到int a = 1这种表达,可是python中怎么没见到这些?

回答这个问题,就得谈谈python中的对象引用机制和动态类型。

的确,python使用变量的时候都没有声明变量的类型,这一点和C语言不同。但是,变量还可以工作,因为在python中类型是在运行的过程中自动决定的,而不是通过代码声明的,这意味着没有必要事先声明变量。

在python中,我们要明确一个概念:变量名和对象是划分开的,变量名永远没有任何关联的类型信息,类型是和对象关联的,而不存在于变量名中。一个变量名当第一次被赋值的时候被创建,而当新的赋值表达式出现时,他会马上被当前新引用的对象所代替。这就是python所谓的动态类型机制。具体看一个例子:



a = 'abcde'

print(a)

a = [1,2,3,4,5]

print(a)





abcde

[1, 2, 3, 4, 5]

结合上面这个简单的例子,我们再来从头仔细理一理:

1、创建了一个字符串对象’abcde’,然后创建了一个变量a,将变量a和字符串对象 ‘abcde’相连接,

2、之后又创建了一个列表对象[1,2,3,4,5],然后又将他和a相连接。

这种从变量到对象的连接,我们称之为引用,以内存中的指针形式实现。因此直白的说,在内部,变量事实上是到对象内存空间的一个指针,而且指向的对象可以随着程序赋值语句而不断变化。

总结一下:变量名没有类型,只有对象才有类型,变量只是引用了不同类型的对象而已。每一个对象都包含了两个头部信息,一个是类型标志符,标识这个对象的类型,以及一个引用的计数器,用来表示这个对象被多少个变量名所引用,如果此时没有变量引用他,那么就可以回收这个对象。

基于上面谈到的引用机制,我们再说说Python的垃圾收集机制。

还是上面那个例子,每当一个变量名被赋予了一个新的对象,那么之前的那个对象占用的空间就会被回收,前提是如果他没有被其他变量名或者对象引用。这种自动回收对象空间的机制叫做垃圾收集机制。

即当a被赋值给列表对象[1,2,3,4,5]时,字符串对象的内存空间就被自动回收(前提是如果他没有被别的变量引用)

具体的内部机制是这样的:python在每个对象中保存了一个计数器,计数器记录了当前指向该对象的引用的数目。一旦这个计数器被设置为0,这个对象的内存空间就会自动回收。当a被赋值给列表对象后,原来的字符串对象‘abcde’的引用计数器就会变为0,导致他的空间被回收。这就使得我们不必像C++那样需要专门编写释放内存空间的代码了

【妹子说】那再说说共享引用的内容吧:

如下所示,多个变量名引用了同一个对象,称为共享引用:

a = 'abcde'

b = a

print(a)

print(b)





abcde

abcde

此时字符串对象’abcde’的引用计数是2,我们进一步往下看如果我们此时对变量a重新赋值呢?

a = 'abcde'

b = a

a = [1,2,3,4]

print(a)

print(b)





[1, 2, 3, 4]

Abcde

结果是显而易见的,变量a变成了列表对象的引用,而变量b依然是字符串对象’abcde’的引用,并且字符串对象的引用计数为由2变为1.

如果此时再对b进行重新赋值,字符串对象‘abcde’的引用计数就会变为0,然后这个对象就被垃圾回收了。


原文发布时间为:2018-08-12

本文作者:给妹子讲python

本文来自云栖社区合作伙伴“Python爱好者社区”,了解相关信息可以关注“Python爱好者社区”。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
Python爱好者
使用钉钉扫一扫加入圈子
+ 订阅

官网链接