我有一个Python脚本'runme.py',我试图从下面的'callerX.py'执行。我正在使用exec(open(filename).read())来完成此任务。正在执行的脚本包含一个简单的类,它试图从全局命名空间和“全局命名空间”调用'time()'函数。在一个函数内部。
在下面的所有示例中,我们使用exec()执行以下文件:
# runme.py
# this code is being exec()'d by the stand-alone examples 1-3 below:
from time import *
class MyClass():
def main(self):
print("Local tracepoint 1")
t = time()
print("Local tracepoint 2")
mc = MyClass()
print("Tracepoint 1")
gt = time()
print("Tracepoint 2")
mc.main()
print("Tracepoint 3")
caller1.py :(这个工作正常,'time'函数可以在MyClass.main()中使用)
print("Run from main scope:")
exec(open("runme.py").read())
def Run():
exec(open("runme.py").read())
print("Run from function:")
Run()
def Run():
exec(open("runme.py").read())
print("Run from main scope:")
exec(open("runme.py").read())
print("Run from function:")
Run()
请注意,在上面的示例中,对'runme.py'的全局命名空间中的time()函数的调用始终有效,并且从MyClass.main()调用time()函数有时只能工作,取决于文件runme.py是否来自函数内的exec()。
如果我们从函数(caller1.py)外部调用exec(),它就可以工作。如果我们从函数(caller2.py)中调用exec(),它将失败并显示异常。如果我们从函数外部调用exec(),然后从函数内部调用(caller3.py),那么两个调用exec()都会运行而没有异常。
此行为似乎不一致。有任何想法吗?我知道这是一个人为的例子,然而,它是从一个更复杂的程序中提炼出来的,这个程序的要求已经把我们带到了这个关键时刻。
答案 0 :(得分:0)
这可能与'from x import *'的工作原理有关。如果你从'top-level'调用它,它将导入整个模块的globals()。
但是,如果在函数内部调用它,它只会导入到函数中的locals()中。 exec()在caller2中的函数内得到评估;因此,import *不会进入globals(),而'inner'主函数看不到它。
顺便说一句:如果您尝试这样的代码,那就很有趣了:
def run():
from time import *
def test():
print time()
test()
run()
你会得到一个异常:SyntaxError:import *在函数'run'中是不允许的,因为它包含一个带有自由变量的嵌套函数
但这正是你对执行官的所作所为,但它却以某种方式令人惊讶地偷偷摸摸。
但是 - 考虑到其他答案 - 为什么不使用其他东西呢?查看'imp'模块文档 - 特别是函数find_module和load_module。
答案 1 :(得分:-1)
这是一个想法:不要使用exec
。基本上每当我看到有人使用exec
或eval
时,都会因为他们不知道已经存在更好的方法来完成相同的事情。它是一个阻碍编写动态代码的拐杖,而不是编写某种动态代码的方法。