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

为何使用exec执行代码时函数无法调用另一个函数?

为何直接调用bar函数正常,但foo内部调用bar却报NameError?

问题代码

py = """
a = 1
print (f'before all {a=}')

def bar(n):
    print(f'bye {n=}')

def foo(n):
    print(f'hello {n=}')
    bar(n)

bar ('just works')    
foo ('sara')
"""

loc = {}
glo = {}
bytecode = compile(py, "script", "exec")
exec(bytecode, glo, loc)

运行结果

before all a=1
bye n='just works'
hello n='sara'
Traceback (most recent call last):
  File "/home/bla-bla/pythonProject/main_deco2.py", line 43, in <module>
    exec(bytecode, glo, loc)
  File "script", line 13, in <module>
  File "script", line 10, in foo
NameError: name 'bar' is not defined

原因分析

核心是Python的名字查找规则和exec传入的双命名空间差异导致的:

  • 顶层调用bar('just works')时,Python会优先在**当前局部命名空间(即你传入的loc字典)**里查找bar,此时bar已经被定义并存入loc,所以能正常执行。
  • 但函数foo在定义时,它的全局作用域被绑定到了你传入的glo字典。当foo内部调用bar时,Python会去foo绑定的全局命名空间(glo)里查找,而bar只被存入loc、未进入glo,所以触发NameError。

解决方法

最直接的方案是统一命名空间,让全局和局部使用同一个字典:

# 方法1:只传全局命名空间,局部会默认复用全局
exec(bytecode, glo)

# 方法2:显式传入同一个字典作为全局和局部
namespace = {}
exec(bytecode, namespace, namespace)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:45:36