类方法中无法通过global修改同名模块级变量,因global仅作用于模块顶层;修改类变量需用类名或__class__;访问同名模块变量须用globals()['x']。

类方法里改不了同名的模块级变量
当你在类的方法中写 x = 10,而模块顶层也有个 x,Python 不会去动那个模块级 x——它直接把你这行当成定义局部变量。哪怕你只是想读取它,只要后面有赋值,整个作用域里这个名字就“被锁死”为局部了。
常见错误现象:UnboundLocalError: local variable 'x' referenced before assignment,尤其出现在 if 分支或 try 块里先读、后赋值的逻辑中。
- 模块级变量(即通常说的“全局变量”)和类变量是两回事:类变量属于类对象,模块级变量属于模块命名空间
-
global x只能绑定到模块顶层的x,对类变量MyClass.x无效 - 类变量修改用
MyClass.x = ...或self.__class__.x = ...,不能靠global
类变量和模块变量同名时,怎么明确访问模块级那个?
如果类里有个 count,模块顶层也有个 count,方法中直接写 count 永远指向局部(如果有赋值)或报错(如果先读后赋)。想安全读写模块级 count,必须显式指定命名空间。
正确做法是用 globals()['count'] ——它绕过作用域查找,直击模块字典。
立即学习“Python免费学习笔记(深入)”;
华为云 Python SDK 查询工具。自动发现已安装 SDK 的服务包、Client类、API 方法、入参详情、类信息(__init__ 参数、属性、类型、描述),支持关键字搜索,快速定位目标 API 使用方法。
- 读取:
print(globals()['count']) - 写入:
globals()['count'] = 42 - 注意:
globals()返回的是当前模块的全局命名空间,不是类或实例的 - 别用
global count去碰类变量;也别用self.count去碰模块变量——两者完全不互通
为什么 global 对类变量不起作用?
global 关键字只影响模块作用域(G),它告诉 Python:“这个变量属于当前模块顶层”。类变量存放在类对象的 __dict__ 里,属于“类命名空间”,不在 global 的管辖范围内。
例如:
counter = 0
<p>class Worker:
counter = 100 # 这是类变量,和上面的 counter 完全无关</p><pre class="brush:php;toolbar:false;">def bump(self):
global counter # 只能改模块级 counter
counter += 1
self.__class__.counter += 1 # 才能改类变量 Worker.counter
- 执行
Worker().bump()后,模块级counter变成 1,Worker.counter变成 101 - 如果误写
global counter却想改类变量,代码不会报错,但目标变量根本没变 - 类变量的增删改查,统一走
类名.变量名或cls.变量名(在类方法中)
嵌套类或方法里容易漏掉的命名冲突点
真正麻烦的不是顶层类,而是嵌套结构:比如类里定义了静态方法,又在其中定义了同名局部变量,再试图通过 globals() 访问模块变量——这时没问题;但如果这个静态方法里还调用了另一个函数,而那个函数又用了 global,就可能意外改掉你没意识到的模块变量。
- 避免在多层嵌套中复用通用名如
data、config、flag - 调试时用
print(locals(), globals().keys())快速确认当前作用域里哪些名字被占用了 - 类变量若需被多个实例共享且可变,优先封装成单例类或用模块级变量 + 显式命名空间前缀(如
MODULE_COUNTER)
最常被忽略的其实是模块级变量和类变量同名时,开发者下意识以为 global 能覆盖一切——其实它连类变量的边都碰不到。真要混用,就得靠 globals() 直接操作,或者干脆重命名隔离。

















