第七章 对象引用、可变性和垃圾回收
7.1 Python变量到底是什么
- 首先Python中的赋值语句是从右向左执行的,即先创建对象,再创建变量,然后把对象赋值给变量。就像往对象上贴了便利贴一样。因此,Python中的变量看做便利贴是很好理解的。所以,变量存储的是对象的内存地址,而不是对象本身,因此不能把对象看做装载对象的容器。Python 语言参考手册中有一句话,“每个变量都有标识、类型和值,对象一旦被创建,他的标识决不会变”。我觉得,作者想表达的应该是,每个对象都有标识、对象和值,对象的标识是类似于一个人的身份证号,能唯一识别一个对象,这里可以简单看做对象存储的内存地址。实际上,每一个变量都是对象的引用,变量中存储的是对象的内存地址。
7.2 ==和is的区别
==比较的是对象的值是否相等,本质上调用了__eq__方法。
def __eq__(self, string):
if isinstance(string, UserString):
return self.data == string.data
return self.data == string
而is比较的是对象的内存地址是否相同,换句话说,两者是否为同一个对象。
import sys
s1 = "adf"
print(sys.getrefcount(s1))
s2 = "adf"
print(sys.getrefcount(s1))
print(s1 is s2)
# 4
# 5
# True
- 我目前使用的Python版本是3.9.1,可以看到,对于一些常见的字符串或者数字,Python为了节约内存,再次创建值相同的对象时,实际上将变量指向了已经创建的字符串或者数字。
7.3 del语句和垃圾回收
对象内部有一个变量ob_refcnt,每当对象被引用一次,ob_refcnt加一,当del语句删除变量,并将ob_refcnt减一,当ob_refcnt减少到0时,对象会被销毁,内存被释放。
typedef struct_object{
int ob_refcnt;
struct_typeobject *ob_type;
}PyObject;
- 关于垃圾回收机制讲解的书籍比较少,垃圾回收主要以引用计数为主,以标记清楚和分代回收为辅。详细的垃圾回收机制可以看这篇文章
https://www.cnblogs.com/pinganzi/p/6646742.html#_label15