
本文详解如何在 python 中将形如 `"x = 5"` 的字符串解析并执行为真实变量赋值,重点说明 `exec` 与 `eval` 的适用场景、局部/全局作用域限制,以及推荐的安全替代方案。
在 Python 中,直接通过字符串动态创建或修改变量(例如将 "X = 5" 转为 X = 5)看似简单,但受语言设计约束,其实现方式需谨慎选择——尤其要区分全局作用域与函数局部作用域。
✅ 全局作用域:可直接使用 exec
在模块顶层(即全局作用域),exec() 是最直接有效的方案:
exec("X = 5")
print(X) # 输出: 5它等价于手动书写 X = 5,因为全局命名空间本质上是 globals() 返回的可变字典。你也可以用更精确的 compile 配合 exec:
exec(compile("X = 5", "", "single")) 其中 "single" 表示单条语句(适合赋值),而 "exec" 支持多行代码块。
⚠️ 局部作用域:exec / eval 无法真正修改局部变量
在函数内部,无法通过 exec 或 eval 动态创建或修改真正的局部变量。原因在于:Python 在编译函数时已静态确定局部变量集合,locals() 返回的是一个只读快照(shallow copy),对其修改不会影响真实栈帧中的变量:
def bad_example():
x = 1
exec("x = 99") # ❌ 无效!x 仍为 1
print(x) # 输出: 1
bad_example()✅ 推荐方案:使用独立作用域字典(安全 & 可控)
最佳实践是显式传入一个 dict 作为执行上下文,所有赋值均发生在此字典中,再从中提取结果:
def safe_assign(statement: str, initial_scope: dict = None) -> dict:
scope = initial_scope.copy() if initial_scope else {}
exec(statement, globals(), scope)
return scope
# 使用示例
result = safe_assign("X = 5; Y = 'hello'; Z = [1, 2, 3]")
print(result['X']) # 5
print(result['Y']) # 'hello'
print(result['Z']) # [1, 2, 3]? 安全提示:exec 和 eval 执行任意字符串存在严重安全风险(如代码注入)。仅在完全信任输入来源时使用;生产环境建议改用 ast.literal_eval()(仅支持字面量)或专用解析器(如 pyparsing)处理结构化赋值。
? 总结
- ✅ 全局赋值:用 exec("X = 5") 简洁有效;
- ❌ 局部赋值:不可动态新增/修改真实 local 变量;
- ✅ 安全替代:始终通过自定义 dict 作用域执行,并显式读取结果;
- ⚠️ 勿滥用:避免对用户输入、配置文件等不可信源直接 exec。
掌握这一机制,既能满足动态脚本化需求,又能守住代码健壮性与安全性底线。










