首先,看一个使用exec的简单的例子:
content = """
class Tool:
def __str__(self):
return "Hello"
"""
if __name__ == "__main__":
exec(content)
print(Tool())
这个例子正常地返回了"Hello"的结果。
但是,当我们在函数或类中运行exec函数后,就会报错。例如以下两种情况。
def f():
exec(content)
print(Tool())
class T:
def __init__(self):
exec(content)
print(Tool())
报错信息为未找到Tool类:
NameError: name 'Tool' is not defined
参考文档如下:文档地址
exec(object[, globals[, locals]])
……如果省略了可选项,代码将在当前作用域内执行。 如果只提供了 globals,则它必须是一个字典(不能是字典的子类),该字典将同时被用于全局和局部变量。 如果同时提供了 globals 和 locals,它们会分别被用于全局和局部变量。……
注解:内置 globals() 和 locals() 函数各自返回当前的全局和本地字典,因此可以将它们传递给 exec() 的第二个和第三个实参。……
猜测可能是因为exec的默认作用域是当前作用域。通过locals()也可以看到Tool类确实存在于locals字典中。
{'self': <__main__.T object at 0x000001CFBA267730>, 'Tool': <class '__main__.Tool'>} # T对象
{'Tool': <class '__main__.Tool'>} # f函数
由此,我们可以通过如下方式使exec在全局范围内运行,解决这个问题。
class T:
def __init__(self):
exec(content,globals())
print(Tool())
def f():
exec(content,globals())
print(Tool())