调用exec,尽管名称已定义,但出现NameError

时间:2018-10-05 21:04:59

标签: python

我有一个名为file.py的文件,其中包含以下脚本:

def b():
    print("b") 
def proc():
    print("this is main")
    b()    
proc()

还有另一个名为caller.py的文件,其中包含以下脚本:

text = open('file.py').read()
exec(text)

当我运行它时,我得到了预期的输出:

this is main 

b

但是,如果我将caller.py更改为此:

def main():
    text = open('file.py').read()
    exec(text)
main()

我收到以下错误:

this is main
Traceback (most recent call last):
  File "./caller.py", line 7, in <module>
    main()
  File "./caller.py", line 5, in main
    exec(text)
  File "<string>", line 10, in <module>
  File "<string>", line 8, in main
NameError: global name 'b' is not defined

函数b()如何丢失?在我看来,我没有违反任何范围规则。我需要进行类似于caller.py第二版的工作。

2 个答案:

答案 0 :(得分:3)

exec(text)在当前范围内执行text,但是未定义该范围(如def b通过隐式分配进行的操作)。

解决方法很简单:

def main():
    text = open('file.py').read()
    exec(text, {})

这导致text在空的 global 范围内运行(使用默认的__builtins对象增强),与在常规Python文件中一样。

有关详细信息,请参见exec documentation。它还警告说,修改默认的本地范围(在未指定text以外的任何参数时暗含)是不合理的:

  

默认的 locals 的行为如以下功能locals()所述:不应尝试对默认的locals字典进行修改。如果需要在函数exec()返回后查看代码对 locals 的影响,请传递一个明确的 locals 字典。

答案 1 :(得分:1)

如果您导入并调用该函数,对您是否有用?

myfile.py

def b():
    print("b") 

def proc():
    print("this is main")
    b()

caller.py

import myfile

myfile.proc()