在文件“A.py”中,我写了一个函数runPyFile
,它就是
exec(open(file).read())
但是现在当我在文件“B.py”中写入时:
from A import *
runPyFile(myFile)
那么在这个 myFile
文件中定义的 values 在“B”文件中不可用。我该怎么做才能在“B”文件中使用它们?
回答1
exec
使用字典来保存执行代码中的全局变量和局部变量。传入 globals()
以使用它所在模块的全局变量。
exec(open(file).read(), globals())
由于您需要能够从其他模块调用它,您可以编写 runPyFile
以便它接受调用者传递的全局字典。然后调用者传递它的 globals()
。
def runPyFile(file, globals):
exec(open(file).read(), globals)
runPyFile(myFile, globals())
通过一点堆栈检查,您可以获得调用者的全局变量,而无需显式传递它们。这是“魔法”并且依赖于特定于 CPython 的细节,因此请谨慎使用。 (如果需要,调用者仍然可以传入自己的全局变量。)
from inspect import currentframe
def runPyFile(file, globals=None):
if globals is None:
globals = currentframe().f_back.f_globals
exec(open(file).read(), globals)
最后,还有只使用您自己的字典而不是模块的全局命名空间的技术。这将执行代码的变量与任何模块的变量隔离开来,并允许您避免覆盖 values 甚至模块中的类和函数。您可以创建一个 dict
子类,让您可以将元素作为属性访问,以便更轻松地访问这些变量。
from inspect import currentframe
class Variables(dict):
__getattr__ = dict.__getitem__
def runPyFile(file, globals=None):
if globals is None:
globals = Variables()
exec(open(file).read(), globals)
return globals
vars = runPyFile(myFile)
print(vars.a) # `a` defined in myFile
vars.func(...) # calls `func` defined in myFile