模块级全局变量本质是模块命名空间内变量,非真正跨进程/跨请求全局,安全使用需明确作用域、避免隐式共享、防止并发污染、适配运行环境。

模块执行上下文中的全局变量,本质是模块级命名空间里的变量,不是真正跨进程/跨请求的“全局”,而是在该模块被导入、执行时所处的 Python 解释器实例中有效。它的安全使用关键在于:明确作用域边界、避免隐式共享、防止并发污染、适配运行环境(尤其是 Web 或多线程场景)。下面从四个实用角度说明。
明确变量归属,统一在模块顶层定义和初始化
所有需跨函数共享的数据,应在模块最外层直接赋值,不嵌套在函数或类内部。初始化必须显式完成,不能依赖首次访问才创建。
- ✅ 推荐写法:config.py 中
DEBUG = True、DB_URL = "sqlite:///app.db" - ❌ 避免写法:
def init_config(): global DB_URL; DB_URL = ...—— 延迟初始化易遗漏,且调用顺序难保证 - 变量名建议全大写加下划线(如
MAX_RETRY_COUNT),与局部变量形成视觉区隔
跨函数修改时,严格使用 global 关键字声明
读取全局变量无需声明;但只要赋值(包括 +=、.append() 等原地修改),就必须在函数开头用 global 明确指出目标变量。
- 例如:
counter = 0定义后,在函数中要改它就得写global counter,否则 Python 默认创建同名局部变量 - 对可变对象(如
list、dict)仅调用方法(如items.append(x))不触发局部化,但重新赋值(items = [...])仍需global - 多个变量用同一行声明更清晰:
global cache, last_updated, is_running
多文件共享时,通过模块导入访问,而非重复定义
不要在多个文件里各自写 global_var = ...;应只在一个模块(如 state.py)中定义,其余文件通过 import state 或 from state import global_var 使用。
- ✅ 正确方式:
state.py定义user_cache = {};api.py中写import state; state.user_cache["u1"] = data - ❌ 错误方式:在
api.py和service.py各自定义user_cache = {}—— 二者完全独立,无法共享状态 - 若需初始化逻辑(如加载配置),放在模块底部的
if __name__ == "__main__":块之外,确保导入即生效
Web 或并发环境必须规避模块级全局变量
Flask、FastAPI、Django 等框架通常以多线程或多进程方式处理请求。模块级全局变量会被所有请求共享,极易引发数据错乱(如 A 请求覆盖 B 请求的临时数据)。
- ❌ 禁止在路由函数中操作模块全局变量存储用户数据
- ✅ 替代方案:
- 用
flask.g(单次请求生命周期) - 用
threading.local()(单线程隔离) - 用数据库、Redis 或内存缓存(跨请求持久化)
- 用
- 若只是读取常量(如
API_VERSION、ALLOWED_ORIGINS),模块全局变量完全安全,无需额外保护











