共计 1455 个字符,预计需要花费 4 分钟才能阅读完成。
一、枚举类
-
定义大量常量
用大写变量定义
JAN = 1 FEB = 2 MAR = 3
问题:不方便管理
-
解决方案
定义一个类,每个常量作为类的一个唯一属性
-
Enum 类实现
from enum import Enum Month = Enum("Month", ("JAN", "FEB", "MAR", "APR")) print(Month, type(Month)) m = Month.__members__.items() print(m, type(m)) for name, member in m: print(name, member, member.value) print(Month.JAN.value)
-
要更精确地控制枚举类型,可以从 Enum 派生出自定义类
# 自定义枚举类 from enum import Enum, unique # 继承了 Enum 的类为枚举类 # 装饰器检查并保证没有重复的变量 @unique class Month(Enum): JAN = 1 FEB = 2 MAR = 300 APR = 4 print(Month.JAN.value) print(Month.MAR.value)
二、垃圾回收机制
-
垃圾回收作用
a、找到内存中无用的垃圾资源
b、清除这些垃圾兵把内存释放出来给其他的对象使用
-
引用计数器
说明:是 python 中默认采用的垃圾回收机制
原理:每个对象维护一个 ob_ref 字段 (属性),用于记录该对象被引用的次数。每当新的引用指向该对象时,它的 ob_ref 加 1。当对象的引用失效时,它的 ob_ref 减 1,一旦对象的引用计数器 ob_ref 为 0,该对象立即被回收,对象所占用的内存空间被释放
优点:简单,实时高效
缺点:
a、需要额外的空间维护引用计数
b、循环引用
class Person(): pass per1 = Person() per2 = per1 del per1 # 删除引用 print(per2) print("------- 循环引用 --------") li1 = [1,2] # li1:1 li2 = [3,4] # li2:1 li1.append(li2) # li1:1 li2:2 li2.append(li1) # li:2 li2:2 del li1 #li1:1 del li2 #li2:1
-
标记清除
概述:基于追踪回收(tracing GC)技术实现的垃圾回收算法
流程:
a、第一阶段是标记阶段,GC 会把所有的『活动对象』打上标记
b、第二阶段是把那些没有标记的对象『非活动对象』进行回收
使用:作为 Python 的辅助垃圾收集技术主要处理的是一些容器对象,比如 list、dict、tuple,instance 等,因为对于字符串、数值对象是不可能造成循环引用问题。Python 使用一个双向链表将这些容器对象组织起来
缺点:除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象
-
分代回收
分代回收是一种以空间换时间的操作方式,Python 将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python 将内存分为了 3“代”,分别为年轻代(第 0 代)、中年代(第 1 代)、老年代(第 2 代),他们对应的是 3 个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python 垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。同时,分代回收是建立在标记清除技术基础之上。分代回收同样作为 Python 的辅助垃圾收集技术处理那些容器对象