当前位置: 首页 > article >正文

【Python语言基础】19、垃圾回收

文章目录

    • 1. 垃圾回收
      • 1.1 引用计数-日常检查货物标签
      • 1.2 标记-清除算法:处理互相依赖的货物
      • 1.3 分代回收:根据货物新旧安排清理频率
    • 2. 特殊方法
      • 2.1 构造和析构方法
      • 2.2 字符串表示方法
      • 2.3 比较方法
      • 2.4 容器相关方法
      • 2.5 可调用对象方法

1. 垃圾回收

计算机的内存想象成一个大仓库,里面存放着各种各样的货物(对象),而 Python 的垃圾回收机制就如同仓库里的清洁工,会定期检查房间(内存),把那些你不再使用的物品(对象)清理掉,释放出空间,让你可以继续使用内存。

而在程序中没有被引用的对象就是垃圾,垃圾对象过多会影响到程序的运行速度。

下面咱们就结合生活场景详细说说。

1.1 引用计数-日常检查货物标签

在这个大仓库中,每一件货物上都挂着标签,每个标签代表着一个对该货物的引用。

比如,有一个叫 “苹果” 的货物,当仓库管理员小王在他的货物清单上记录了 “苹果” 时,“苹果” 这个货物就有了一个标签,代表小王引用了它。

# 仓库里新来了一批苹果
apples = ["红富士", "蛇果"]  
# 小李也在他的清单上记录了苹果
other_apples = apples  

此时,“苹果” 货物上就有了两个标签,意味着它的引用计数是 2。

当小王不再需要 “苹果” 了,他会从自己的清单上划掉 “苹果”,这就相当于删除了一个引用。

# 小王不再关注苹果了
del apples  

这时,“苹果” 货物上就只剩下一个标签,引用计数变为 1。
如果小李也不再需要 “苹果”,从他的清单上划掉 “苹果”,引用计数就变为 0。

# 小李也不再关注苹果了
del other_apples  

一旦引用计数为 0,清洁工(垃圾回收机制)就会立刻发现,然后把 “苹果” 货物从仓库中清理出去,释放出存放 “苹果” 的空间。

1.2 标记-清除算法:处理互相依赖的货物

有时候,仓库里会出现一些特殊情况,有两件货物相互捆绑在一起,而且没有其他地方提到它们。
比如,“箱子” 货物里面装着 “钥匙” 货物,同时 “钥匙” 又能打开 “箱子”,它们相互依赖。

class Box:passclass Key:pass# 仓库里有了一个箱子和一把钥匙
box = Box()
key = Key()
# 箱子里装着钥匙
box.key = key
# 钥匙能打开箱子
key.box = box
# 仓库管理员不再需要它们了
del box
del key

在这种情况下,“箱子” 和 “钥匙” 虽然看起来没人要了,但因为它们相互引用,各自的引用计数都不为 0。
这时,日常检查标签的方法(引用计数)就失效了。

于是,清洁工就会启动标记 - 清除算法。他先把仓库里所有的货物都标记为 “可能要清理”,然后从仓库的入口(根对象,如全局变量)开始,沿着货物之间的关联关系进行检查。
如果发现某个货物可以从入口到达,就把它标记为 “保留”。经过一轮检查后,那些仍然标记为 “可能要清理” 的货物,就是真正的垃圾,清洁工就会把它们清理掉。

1.3 分代回收:根据货物新旧安排清理频率

仓库里的货物有新有旧,有些货物刚进来没多久就可能会被处理掉,而有些货物则会长期存放在仓库里。

清洁工根据这个特点,把货物分成了三代。

新进入仓库的货物属于第 0 代,清洁工对第 0 代货物的检查频率最高,因为它们很可能很快就会变成垃圾。
经过一次检查后还没被清理掉的货物,就会被移到第 1 代。第 1 代货物的检查频率会相对低一些。
而那些经过多次检查都还没被清理的货物,会被移到第 2 代,第 2 代货物的检查频率最低。

# 这是新进来的第 0 代货物
new_item = [1, 2, 3]
# 经过一段时间,new_item 如果没被清理,可能会进入第 1 代
# 再经过一段时间,如果还没被清理,可能会进入第 2 代

通过这种分代回收的方式,清洁工可以更高效地管理仓库空间,优先处理那些更可能成为垃圾的货物。

总结
Python 的垃圾回收机制就像这位聪明的清洁工,通过引用计数、标记 - 清除算法和分代回收算法,有条不紊地管理着计算机的内存仓库。

2. 特殊方法

在 Python 里,特殊方法(也叫魔术方法)是一类具有特殊名称的方法,它们的名字以双下划线 __ 开头和结尾。这些方法能让你自定义类的行为,使类的使用更符合 Python 的习惯。

特殊方法一般不需要我们手动调用,需要在一些特殊情况下自动执行

2.1 构造和析构方法

  • __init__:这是最常用的特殊方法之一,用于在创建对象时进行初始化操作。
class Person:def __init__(self, name, age):self.name = nameself.age = agep = Person("张三", 25)
  • __del__:当对象被销毁时会调用这个方法,可用于执行一些清理操作,比如关闭文件、释放资源等。
class Resource:def __init__(self):print("资源已创建")def __del__(self):print("资源已释放")r = Resource()
del r

2.2 字符串表示方法

  • __str__:用于返回对象的字符串表示形式,通常供用户阅读。当使用 print 函数打印对象或使用 str() 函数转换对象时会调用该方法。
class Book:def __init__(self, title):self.title = titledef __str__(self):return f"这本书的名字是 {self.title}"book = Book("Python入门")
print(book)
  • __repr__:返回对象的 “官方” 字符串表示形式,通常用于调试和开发。当在交互式环境中直接输入对象名或使用 repr() 函数时会调用该方法。
class Point:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f"Point({self.x}, {self.y})"point = Point(1, 2)
print(repr(point))

2.3 比较方法

  • __eq__:用于定义对象的相等比较规则,当使用 == 运算符比较两个对象时会调用该方法。
class Student:def __init__(self, id):self.id = iddef __eq__(self, other):return self.id == other.ids1 = Student(1)
s2 = Student(1)
print(s1 == s2)

类似的还有 ne(不等于)、lt(小于)、le(小于等于)、gt(大于)、ge(大于等于)等方法。

2.4 容器相关方法

  • __len__:用于返回对象的长度,当使用 len() 函数时会调用该方法。
class MyList:def __init__(self, items):self.items = itemsdef __len__(self):return len(self.items)my_list = MyList([1, 2, 3])
print(len(my_list))
  • __getitem__:用于实现通过索引访问对象中的元素,当使用 obj[index] 这种方式访问对象时会调用该方法。
class MyList:def __init__(self, items):self.items = itemsdef __getitem__(self, index):return self.items[index]my_list = MyList([1, 2, 3])
print(my_list[1])

还有 setitem(用于设置元素)、delitem(用于删除元素)等方法。

2.5 可调用对象方法

  • __call__:让对象可以像函数一样被调用。
class Adder:def __call__(self, a, b):return a + badder = Adder()
result = adder(3, 5)
print(result)

相关文章:

【Python语言基础】19、垃圾回收

文章目录 1. 垃圾回收1.1 引用计数-日常检查货物标签1.2 标记-清除算法:处理互相依赖的货物1.3 分代回收:根据货物新旧安排清理频率 2. 特殊方法2.1 构造和析构方法2.2 字符串表示方法2.3 比较方法2.4 容器相关方法2.5 可调用对象方法 1. 垃圾回收 计算…...

用户自定义函数(UDF)开发与应用(二)

五、UDF 在不同平台的应用 5.1 数据库中的 UDF 应用(如 MySQL、PostgreSQL) 在数据库领域,UDF 为开发者提供了强大的扩展能力,使得数据库可以完成一些原本内置函数无法实现的复杂操作。 以 MySQL 为例,假设我们有一…...

从三次方程到复平面:复数概念的奇妙演进(二)

注:本文为 “复数 | 历史 / 演进” 相关文章合辑。 因 csdn 篇幅限制分篇连载,此为第二篇。 生料,不同的文章不同的点。 机翻,未校。 History of Complex Numbers 复数的历史 The problem of complex numbers dates back to …...

深入剖析缓存一致性问题:延时双删的利弊与替代方案

在当今的分布式系统架构中,缓存凭借其快速的数据读取能力,成为提升系统性能和响应速度的关键组件。然而,缓存的引入也带来了缓存一致性问题,这一问题成为开发者在系统设计与维护中必须攻克的难关。缓存一致性问题聚焦于数据更新时…...

基于视觉语言模型的机器人实时探索系统!ClipRover:移动机器人零样本视觉语言探索和目标发现

作者:Yuxuan Zhang 1 ^{1} 1, Adnan Abdullah 2 ^{2} 2, Sanjeev J. Koppal 3 ^{3} 3, and Md Jahidul Islam 4 ^{4} 4单位: 2 , 4 ^{2,4} 2,4佛罗里达大学电气与计算机工程系RoboPI实验室, 1 , 3 ^{1,3} 1,3佛罗里达大学电气与计算机工程系F…...

LabVIEW往复式压缩机管路故障诊断系统

往复式压缩机作为工业领域的关键设备,广泛应用于石油化工、能源等行业,承担着气体压缩的重要任务。然而,其管路故障频发,不仅降低设备性能、造成能源浪费,还可能引发严重安全事故。因此,开发精准高效的管路…...

wsl下编译eXosip和osip库(Ubuntu 22.04)

1.下载eXosip和osip osip下载路径 Index of /mirror/gnu.org/savannah/osip eXosip下载路径 Index of /nongnu/exosip 我选的osip和eXosip版本为 5.2.0 2.编译osip库 tar -zxvf libosip2-5.2.0.tar.gz cd libosip2-5.2.0 ./configure make make install 在编译…...

springboot 项目 jmeter简单测试流程

测试内容为 主机地址随机数 package com.hainiu.example;import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotat…...

程序化广告行业(82/89):解锁行业术语,开启专业交流之门

程序化广告行业(82/89):解锁行业术语,开启专业交流之门 在程序化广告这个充满活力与挑战的行业里,持续学习是我们不断进步的动力源泉。一直以来,我都期望能和大家一起深入探索这个领域,共同成长…...

算法思想之位运算(二)

欢迎拜访:雾里看山-CSDN博客 本篇主题:算法思想之位运算(二) 发布时间:2025.4.13 隶属专栏:算法 目录 滑动窗口算法介绍六大基础位运算符常用模板总结 例题判定字符是否唯一题目链接题目描述算法思路代码实现 汉明距离题目链接题目…...

Collection vs Collections:核心区别与面试指南

Collection vs Collections:核心区别与面试指南 一、本质区别(核心记忆点) 维度CollectionCollections身份集合框架的根接口操作集合的工具类包位置java.utiljava.util是否可实例化❌ 接口✅ 类(但构造器私有,不可实…...

win10中快速访问部分外网的快捷设置方法

目的 不翻墙而访问一些本来访问很慢的网站。 具体操作 例如想要访问 github 网站,首先在终端(Terminal,cmd或powershell)中通过 ping github.com 判断网站是否可以被ping到: 若返回 Request time out. 则说明本方法不可用。若收到Reply&am…...

【计网】网络交换技术之报文交换(复习自用,了解,重要3)

复习自用的,处理得比较草率,复习的同学或者想看基础的同学可以看看,大佬的话可以不用浪费时间在我的水文上了 另外两种交换技术可以直接点击链接访问相关笔记: 电路交换 分组交换 一、报文交换的定义 报文交换(Me…...

【Web功能测试】Web商城搜索模块测试用例设计深度解析

Web商城的搜索模块功能测试用例设计 1.搜索功能设计 1.1 搜索框设计 位置显眼:通常置于页面顶部中央,符合用户习惯。 智能提示(Autocomplete):输入时实时推荐关键词、商品或分类(如“手机 苹果”&#x…...

穿梭在数字王国:Python进制转换奇遇记

穿梭在数字王国:Python进制转换奇遇记 想象一下,你是一位勇敢的探险家,正在穿越神秘的"数字王国"。在这个王国里,不同的地区使用着不同的语言(或者说,进制)。二进制村的居民只懂"0"和"1";八进制镇的人们使用0到7的数字;而十六进制城的…...

【动态规划】深入动态规划:背包问题

文章目录 前言01背包例题一、01背包二、分割等和子集三、目标和四、最后一块石头的重量|| 完全背包例题一、完全背包二、 零钱兑换三、零钱兑换||四、完全平方数 前言 什么是背包问题,怎么解决算法中的背包问题呢? 背包问题 (Knapsack problem) 是⼀种组…...

BUUCTF-web刷题篇(25)

34.the mystery of ip 给出链接,输入得到首页: 有三个按钮,flag点击后发现页面窃取客户端的IP地址,通过给出的github代码中的php文件发现可以通过XFF或Client-IP传入值。使用hackbar或BP 使用XSS,通过github给出的目录…...

StringBuilder类基本使用

文章目录 1. 基本介绍2. StringBuilder常用方法3. String、StringBuffer 和 StringBuilder 的比较4. String、StringBuffer 和 StringBuilder 的效率测试5. String、StringBuffer 和 StringBuilder 的选择 1. 基本介绍 一个可变的字符序列。此类提供一个与StringBuffer兼容的A…...

设计模式 --- 访问者模式

访问者模式是一种行为设计模式,它允许在不改变对象结构的前提下,定义作用于这些对象元素的新操作。 优点: 1.​​符合开闭原则:新增操作只需添加新的访问者类,无需修改现有对象结构。 ​​2.操作逻辑集中管理​​&am…...

常用AI辅助编程工具及平台介绍

在当今快速发展的技术领域,AI编程工具已经成为提升开发效率和代码质量的重要手段。这些工具利用人工智能技术来帮助开发者提高编程效率、生成代码建议、自动完成功能,并识别错误。接下来,我们将详细介绍几款主流的AI编程工具及其特点,以帮助你选择最适合自己的开发需求的工…...

HashTable,HashMap,ConcurrentHashMap之间的区别

文章目录 线程安全方面性能方面总结 线程安全方面 HashMap线程不安全,HashMap的方法没有进行同步,多个线程同时访问HashMap,并至少有一个线程修改了其内容,则必须手动同步。 HashTable是线程安全的,在HashMap的基础上…...

LeetCode.225. 用队列实现栈

用队列实现栈 题目解题思路1. push2. pop3. empty CodeQueue.hQueue.cStack.c 题目 225. 用队列实现栈 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 实现…...

LVGL AnalogClock控件和Dclock控件详解

LVGL AnalogClock控件和Dclock控件详解 一、AnalogClock控件详解1. 概述2. 创建模拟时钟2.1 函数2.2 参数2.3 返回值 3. 设置时间3.1 函数3.2 参数 4. 获取时间4.1 函数4.2 参数 5. 设置样式5.1 常用样式属性5.2 示例代码 6. 更新时间6.1 定时器回调示例6.2 创建定时器 7. 示例…...

通过分治策略解决内存限制问题完成大型Hive表数据的去重的PySpark代码实现

在Hive集群中,有一张历史交易记录表,要从这张历史交易记录表中抽取一年的数据按某些字段进行Spark去重,由于这一年的数据超过整个集群的内存容量,需要分解成每个月的数据,分别用Spark去重,并保存为Parquet文…...

深入解析 HTML 中 `<script>` 标签的 async 和 defer 属性

一、背景与问题 在网页性能优化中&#xff0c;脚本的加载和执行方式直接影响页面渲染速度和用户体验。传统 <script> 标签的阻塞行为可能导致页面“白屏”&#xff0c;而 async 和 defer 属性提供了非阻塞的解决方案。本周重点研究二者的差异、适用场景及实际应用。 二、…...

CSS 背景属性学习笔记

CSS 背景属性用于定义 HTML 元素的背景效果&#xff0c;包括背景颜色、背景图像、图像平铺方式、图像定位以及图像是否固定等。以下是关于 CSS 背景属性的详细学习笔记。 一、背景颜色&#xff08;background-color&#xff09; background-color 属性用于定义元素的背景颜色…...

WT-yolo数据集配置文件data.yaml的写法示例

YOLO 的 data.yaml 配置文件用于定义数据集的结构和类别信息。这里列出几种常见的写法和示例&#xff0c;在正式训练时需要根据实际需求正确配置 data.yaml 文件。 1. 基础配置&#xff08;相对路径&#xff09; 这是最常见的写法&#xff0c;使用相对路径来指定训练集、验证…...

【C++初学】课后作业汇总复习(七) 指针-深浅copy

1、 HugeInt类:构造、、cout Description: 32位整数的计算机可以表示整数的范围近似为&#xff0d;20亿到&#xff0b;20亿。在这个范围内操作一般不会出现问题&#xff0c;但是有的应用程序可能需要使用超出上述范围的整数。C可以满足这个需求&#xff0c;创建功能强大的新的…...

探索加密期权波动率交易的系统化实践——动态对冲工具使用

Trading Volatility – What Are My Options? 在本文中&#xff0c;我们将介绍一些如何交易资产波动性&#xff08;而非资产价格&#xff09;的示例。为了帮助理解&#xff0c;我们将使用 Deribit 上提供的几种不同产品&#xff0c;包括但不限于期权。我们将尽可能消除对标的价…...

方案精读:51页 财政数据信息资源目录数据标准存储及大数据资产化规划方案【附全文阅读】

该方案聚焦财政数据信息资源管理,适用于财政部门工作人员、数据管理与分析人员以及关注财政大数据应用的相关人士。 方案旨在构建财政数据资源目录,推动大数据在财政领域的应用与落地。整体规划上,以 “金财工程” 应用支撑平台为基础,建立省、市、县三级目录体系,遵循相关…...