类变量和全局变量的生命周期有什么区别?

Python:类变量 vs 全局变量 --- 生命周期区别

核心一句话: 全局变量依附模块;类变量依附类对象。谁的宿主活着,变量就活着;宿主被 GC 回收,变量跟着销毁。

一、全局变量

全局变量定义在模块顶层,保存在模块对象的 __dict__。

  1. 创建时机 模块被第一次导入(import)的时候,执行模块代码,创建全局变量。
  2. 存活期间 模块一旦导入成功,模块对象会一直驻留内存 ,放到 sys.modules 缓存。 只要进程没结束,模块就不会被回收;全局变量一直存在。 即使你不再使用模块里的函数,模块对象依然在 sys.modules,全局变量保留。
  3. 销毁时机
    • 正常情况:程序进程退出时才销毁
    • 极少数场景:手动从sys.modules删除模块引用 + 无任何其他引用,才会 GC 回收模块,全局变量随之释放(实际开发极少这么做)

特点:生命周期很长,几乎贯穿整个程序运行期。

二、类变量

类变量写在class内部、方法之外,保存在类对象的 __dict__。

  1. 创建时机 执行 class 定义语句那一刻,Python 会创建类对象,同时生成类变量。

    复制代码
    class A:
        x = 10   # 执行class这一行,就创建类变量x
  2. 存活期间 只要类对象还有引用 ,类变量就存在。 引用来源可以是:

    • 类名本身 A
    • 类的实例
    • 其他地方保存的类引用
  3. 销毁时机 当类对象所有引用全部消失 ,GC 把类对象回收,类变量跟着一起销毁。

    • 如果这个类一直被引用(比如全局作用域定义的类),类变量就和全局变量一样活到程序结束;
    • 如果函数内部动态定义 class,函数执行完没有外部引用,类对象就会被 GC,类变量直接释放。

示例:

复制代码
def create_class():
    class Temp:
        val = 99
    return Temp()

obj = create_class()
# 只要obj还在,Temp类对象就存在,Temp.val类变量存活

del obj
# obj删除后,如果没有任何地方引用Temp类,类对象被GC,val销毁

三、关键差异点

  1. 宿主不同
  • 全局变量:宿主是模块对象,模块一旦缓存进 sys.modules 很难回收。
  • 类变量:宿主是类对象,类对象满足无引用条件就可以 GC。
  1. 生命周期灵活性
  • 全局变量:一旦导入,基本常驻内存,很难主动释放。
  • 类变量:可以随类对象销毁而释放。动态创建的类,用完即可回收,内存可以释放。
  1. 定义位置带来的常见现象 很多类写在模块顶层,这时类对象本身就是全局的,类变量也会活到程序结束,看起来生命周期和全局变量一样。

这是很多人容易混淆的点:不是类变量天生短命,是看类对象的引用是否还存在。

  1. 实例删除,不影响类变量 就算所有实例全部 del,只要类本身还在,类变量依然存活。

    class A:
    x = 1
    a1 = A()
    del a1
    print(A.x) # 仍然存在,类对象A还在

四、对比表

表格

项目 全局变量 类变量
归属宿主 模块对象 类对象
创建时机 模块第一次 import,执行模块代码 执行class定义语句时创建
销毁条件 模块从 sys.modules 移除 + 无引用;一般进程结束销毁 类对象全部引用消失,GC 回收类对象,类变量销毁
是否可主动回收 很难,模块会被 sys.modules 缓存 可以,解除类的所有引用即可被 GC
实例删除影响 无关 删除实例,只要类还在,类变量不变
典型生命周期 几乎贯穿整个程序 可长可短;顶层定义类则常驻,动态类用完可回收

五、简单总结

  1. 模块顶层定义的全局变量:程序启动导入后一直存活,直到程序退出。
  2. 类变量的生命周期绑定类对象 :

如果你想,我可以用代码配合gc模块演示,看类对象什么时候被垃圾回收。

相关推荐
code2cat1 小时前
Java进阶篇之AtomicReference:一次替换引用,读到一份完整状态
java·并发编程·不可变对象·atomicreference
专业程序开发源1 小时前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
Wang's Blog1 小时前
Java 项目实战: 外卖平台优化-前后端分离开发模式与工程拆分
java·开发语言
Dovis(誓平步青云)2 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
HEJOO92 小时前
指针的算术运算详解
java·数据结构·算法
sunshine22 girl2 小时前
Java学习六 Java常见API-2--String-3-字符串的截取替换和其他方法
java·开发语言·学习
LOVE️YOU2 小时前
Python 函数名、函数对象与“把函数作为参数传递”
开发语言·python
EatFan2 小时前
从“框架混战“到“运行时收敛“:2026 年 AI Agent 开发框架的三条路线之争
java·数据库·人工智能·多智能体·ai agent·mcp·agent 框架
小蒜学长2 小时前
基于SpringBoot的佳新超市管理系统设计与实现系统(代码+数据库+LW)
java·数据库·spring boot·后端·佳新超市管理系统