在函数内部调用exec(open().read())的Python3-问题

我在我根本不理解的python脚本时遇到问题:

假设我们在同一目录中有2个文件:“ init.py”和“ text.py”

init.py:

X = 5
print("init.py was run")

test.py:

exec(open("./init.py").read())
print("X = %s" %X)

如果我现在运行test.py,我会得到

init.py was run

X = 5

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

def func_call( filename):
  exec(open(filename).read())
  print("X = %s" %X)

func_call("./init.py")

我得到:

init.py was run

Traceback (most recent call last):

File “test.py”, line 5, in

06003

File “test.py”, line 3, in func_call

06004

NameError: name ‘X’ is not defined

有人可以向我解释为什么这会导致不同的结果吗?
有没有解决方法?
我的目标是通过运行python脚本并访问在该python脚本中设置的变量来初始化大多数变量.

最佳答案

根据exec_documentation

If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.

内部方法globals()和locals()是不同的对象:

def method():
    print(globals() == locals())
    exec('X=10')
    print('Method execution =', X)

method()

输出:

False
NameError: name 'X' is not defined

在全局级别上,这些对象相等:

print(globals() == locals())
exec('X=99')
print('Global exec =', X)

输出:

True
Global exec = 99

因此,如果要通过方法执行此操作,则需要将同一对象传递给exec.对于您的代码,它看起来像这样:

def func_call(filename):
  exec(open(filename).read(), globals(), globals())
  print("X = %s" %X)

func_call("./init.py")

但是,正如我在评论中提到的那样,使用const创建文件并将其导入.除非您百分百确定自己在做什么,否则请尽量避免不惜一切代价使用exec / eval.