You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用compile+exec执行赋值代码在函数内报NameError全局运行正常

Python exec函数在函数作用域与全局作用域的行为差异问题解答

成因

Python函数的局部变量在代码编译阶段就会确定存储位置,exec动态执行代码新增的变量不会被纳入函数的静态局部变量列表:

  • 全局作用域下执行exec时,代码中定义的变量会直接写入全局命名空间,后续访问可以正常找到对应变量。
  • 函数作用域下默认执行exec时,变量会写入函数的局部命名空间字典,但解释器访问局部变量时不会扫描这个动态字典,只会去查找编译阶段确定的静态局部变量,因此找不到动态生成的n,抛出NameError。

解决方案

方案1:显式传入自定义命名空间,主动获取变量

最安全的方案,不会污染全局或局部命名空间:

def main():
    c = compile("n = int(input('>>>'))", "", "single")
    # 用自定义字典存储exec执行生成的变量
    namespace = {}
    exec(c, namespace)
    # 从自定义字典中取出变量
    n = namespace['n']
    print(n)

方案2:指定exec写入全局命名空间

适合需要把变量设为全局的场景:

def main():
    c = compile("n = int(input('>>>'))", "", "single")
    # 传入globals()指定将变量写入全局命名空间
    exec(c, globals())
    print(n)

方案3:直接从locals()字典读取动态变量

不需要额外定义字典时可使用:

def main():
    c = compile("n = int(input('>>>'))", "", "single")
    exec(c)
    # 直接从局部命名空间字典中读取动态生成的变量
    print(locals()['n'])

内容的提问来源于stack exchange,提问作者Waylan Punch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 01:45:03