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

3

我是一个有用的助手,可以翻译文本。

我遇到了一个问题,在运行一个Python脚本中,我对其中的一些内容非常不理解:

假设我们在同一个目录下有两个文件:'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被运行

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

func_call("./init.py")   

File "test.py", line 3, in func_call

print("X = %s" %X) 

NameError: name 'X' is not defined

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


为什么不创建const.py文件并进行导入呢? - How about nope
那真的有效并解决了问题,谢谢!但是我仍然不明白为什么会发生这种情况... - Smudoxo
1个回答

5

根据exec_documentation

如果在exec中传递两个分离的对象作为全局和局部命名空间,代码将被执行,就好像它嵌入在类定义中一样。

在方法内部,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")

然而,如我在评论中提到的那样,创建一个包含常量的文件并导入它。尽可能避免使用exec/eval,除非你对自己所做的内容有100%的把握。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接