【问题标题】:Python3-Issue with calling exec(open().read()) inside a functionPython3-在函数内部调用 exec(open().read()) 的问题
【发布时间】:2018-02-17 03:38:13
【问题描述】:

我在我根本不理解的 python 脚本中运行 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 已运行

X = 5

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

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

func_call("./init.py")

我明白了:

init.py 已运行

Traceback(最近一次调用最后一次):

文件“test.py”,第 5 行,在

func_call("./init.py")   

文件“test.py”,第 3 行,在 func_call 中

print("X = %s" %X) 

NameError:名称“X”未定义

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

【问题讨论】:

标签: python python-3.x file exec


【解决方案1】:

根据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")

尽管如此,正如我在评论中提到的,使用 consts 创建文件并导入它。尽量避免使用 exec/eval,除非您 100% 确定自己在做什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 2021-06-15
    相关资源
    最近更新 更多