0

我有一个包含多个函数定义的模块对象。这是一个简化的例子。

源代码(组成模块“my_module”)

def functionA():
    print("hello")

def functionB():
    functionA()
    print("world")

该模块是用 imp 构建的(我知道它已被贬值,但我的应用程序仍在 python 3.5 上)

ast_node = parse(source)
byte_code = compile(ast_node, 'my_module', 'exec')
my_module = imp.new_module('my_module')
exec(byte_code, __builtins__, my_module.__dict__)

我正在尝试functionB()使用exec完整模块__dict__并将其作为本地字典传递。(我也尝试将它作为全局字典传递,但没有任何运气)

exec("functionB()", None, my_module.__dict__)

我看到的错误是NameError: name 'functionA' is not defined

是否可以将本地(甚至全局)范围扩展到执行功能?

4

1 回答 1

1

您不需要“扩展范围”。您的问题是您在错误的名称空间中做事。当您执行模块的代码时:

exec(byte_code, __builtins__, my_module.__dict__)

当您应该将模块的命名空间用作全局变量时,您正在使用内置命名空间作为全局变量:

exec(byte_code, my_module.__dict__)

然后模块的函数将具有正确的全局命名空间。目前,他们都使用内置命名空间作为他们的全局命名空间。

另外,不要__builtins__用于内置命名空间。这是一个实现细节,它甚至不像你想象的那样工作——它的价值在不同的上下文中是不同的。有时它被设置为builtins模块本身,而不是该模块的字典。相反,如果您需要内置字典,请import builtins使用。builtins.__dict__

于 2021-08-09T23:58:15.477 回答