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

标签 python python-3.x file exec

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

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

初始化文件:

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

测试.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

func_call("./init.py")   

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

print("X = %s" %X) 

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

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

关于Python3-在函数内调用 exec(open().read()) 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46112605/

相关文章:

python - 为什么我无法导入 ABC,但 ABCMeta 却正确导入?

python - 使用 conda 和 python3k 构建包

python - 如果密码正确,如何发现 'Access granted' 被打印了 3 次?

java - Maven zip 程序集,包括子目录内容

Python - 在 XML 文档中查找元素的最快方法

Python 函数之争

python - 对于 pandas 数据框中的特定单元格,删除列表的元素

java - java中字符串分词器的错误用法

c - 为什么这个循环不连续打印相同的值?

python - 使用 sqlalchemy + Pyodbc 连接到特定数据库