我想要从一个字典动态地创建一个模块,我在想是否将一个元素添加到sys.modules
真的是最好的方法。例如:
context = { a: 1, b: 2 }
import types
test_context_module = types.ModuleType('TestContext', 'Module created to provide a context for tests')
test_context_module.__dict__.update(context)
import sys
sys.modules['TestContext'] = test_context_module
我在这方面的直接目标是能够为时间测试执行提供上下文:
import timeit
timeit.Timer('a + b', 'from TestContext import *')
似乎还有其他方法可以做到这一点,因为 Timer 构造函数不仅接受字符串,也接受对象。但我仍然希望学习如何做到这一点,因为 a) 它有其他潜在应用; b) 我不确定如何将对象与 Timer 构造函数一起使用;这样做在某些情况下可能不如本方法合适。
修改/揭示/咯咯声/欧瑞卡:
- 我意识到与运行计时测试相关的示例代码实际上无法工作,因为
import *
只在模块级别有效,并且执行该语句的上下文是testit
模块中的 函数,换句话说,当执行该代码的全局字典是__main__
的,因为我在交互式 shell 中编写代码时处于该位置。因此,这个理由有点失败了,但仍然是一个有效的问题。 - 我发现在第一组示例中运行的代码的不良影响是,新创建的模块代码所在的名称空间是其被声明的模块的名称空间,而不是 它自己的模块。这就像非常奇怪,并可能导致各种意外的问题。因此,我相当确定这不是这种事情应该完成的方式,如果 Guido 确实支持它。
- 从未在python的 include 路径中的文件中动态加载模块的类似但微妙的不同的情况可以很容易地使用
imp.load_source('NewModuleName', 'path/to/module/module_to_load.py')
实现。这确实将该模块加载到sys.modules
中。然而,这并不真正回答我的问题,因为实际上,如果你在没有文件系统的嵌入式平台上运行 python,该怎么办?
imp
模块中没有任何能够做到这一点的东西。但是,从本质上讲,问题在于如何设置对象的全局(即模块)上下文。也许我应该更具体地询问这个问题?而且从更大的范围来看,如何在将对象塞入给定模块的同时让 Python 这样做呢?
import *
只在模块级别起作用。 - intuitedimp
模块中有一个叫做new_module
的函数。除了前者不接受文档字符串作为参数外,我不确定imp.new_module和types.ModuleType之间是否有任何区别。它们都不会将新模块添加到sys.modules中;imp.new_module的文档明确提到新模块不会被添加。 - intuited