我想从字典中动态创建一个模块,我想知道添加一个元素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 构造函数中使用对象;在某些情况下,这样做可能被证明不如这种方法合适。
编辑/启示/PHOOEYS/EUREKAE:
我已经意识到与运行时序测试相关的示例代码实际上不起作用,因为
import *
仅在模块级别起作用,并且执行该语句的上下文是模块中函数的上下文testit
。换句话说,执行该代码时使用的全局字典是 of 的字典__main__
,因为那是我在交互式 shell 中编写代码时所在的位置。因此,弄清楚这一点的理由有点拙劣,但这仍然是一个有效的问题。我发现在第一组示例中运行的代码具有不良影响,即新创建的模块代码执行的命名空间是声明它的模块的命名空间,而不是 它自己的模块。这很奇怪,可能会导致各种意想不到的响尾蛇粗略。所以我很确定这不是这种事情的本意,如果这实际上是 Guido 所照耀的事情。
从不在 python 的包含路径中的文件动态加载模块的类似但微妙不同的情况很容易使用
imp.load_source('NewModuleName', 'path/to/module/module_to_load.py')
. 这确实将模块加载到sys.modules
. 但是,这并不能真正回答我的问题,因为实际上,如果您在没有文件系统的嵌入式平台上运行 python怎么办?
我目前正在与一个相当大的信息过载情况作斗争,所以我可能会弄错,但模块中似乎没有任何东西imp
能够做到这一点。
但是,从本质上讲,此时的问题是如何为对象设置全局(即模块)上下文。也许我应该更具体地问这个?在更大的范围内,如何让 Python 在将对象硬塞到给定模块中时做到这一点?