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

Python编译含相互调用函数的AST时出现NameError问题求助

问题分析与解决

问题原因

你遇到的NameError本质是Python的名字作用域静态分析和exec()的命名空间规则共同导致的:

  • Python函数在编译阶段会静态分析内部引用的名字,fn里的fn_2会被标记为全局名字;
  • 当在函数main内部直接调用exec()时,默认会使用main的局部命名空间,而fn_2被定义在这个局部命名空间中,不属于全局命名空间;
  • 因此fn执行时会去全局命名空间查找fn_2,自然找不到。

解决方案

给exec()传入一个独立的字典作为全局命名空间,这样生成的所有函数都会被存入这个字典,函数内部的全局引用会指向该命名空间,相互调用就能正常工作:

def main():
    str = """
def fn_2():
    print("got so far")
        
def fn(input):
    fn_2()

fn("abc")
"""    
    # 创建独立的命名空间字典
    exec_namespace = {}
    mod = compile(str, "testing", 'exec')
    # 将命名空间传入exec
    exec(mod, exec_namespace)

if __name__ == "__main__":
    main()

补充说明

你第二个测试案例能运行,是因为原始文件中定义了全局的fn_2,exec()里的fn调用的是这个全局版本,而非你在字符串中定义的fn_2——这也是为什么注释掉字符串里的fn定义后还能运行(此时调用的fn应为你之前代码中定义的全局fn,案例代码可能存在笔误,但核心逻辑是全局命名空间的fn_2被成功找到)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:32:02