组团学

面向对象-枚举与垃圾回收

阅读 (179041)

一、枚举类

  • 定义大量常量

    用大写变量定义

    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的辅助垃圾收集技术处理那些容器对象

需要 登录 才可以提问哦