社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

给妹子讲python-S01E10python的动态类型与共享引用机制分析

酱油哥在掘金 • 6 年前 • 408 次点击  
阅读 2

给妹子讲python-S01E10python的动态类型与共享引用机制分析

欢迎关注公众号:python数据科学家

【要点抢先看】

1.python采用了动态类型机制
2.python变量本质上是对内存空间的指针
3.python的垃圾收集机制
4.python的共享引用现象

【妹子说】这段时间以来,我一直有个疑问,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,然后这个对象就被垃圾回收了。

【妹子说】这一集感觉聊的很细,我来总结一下:给一个变量赋一个新值,并不是替换原始对象,而是让这个变量去引用完全不同的另一个对象,而原来对象的引用计数会随之减1。好好梳理梳理这些概念吧,很有用的~

公众号二维码:python数据科学家:


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/gFGeLgZnx6
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/20985
 
408 次点击