int*_*ted 12 python module timing dynamic
我想从字典中动态创建一个模块,我想知道添加元素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
Run Code Online (Sandbox Code Playgroud)
我在这方面的近期目标是能够为计时测试执行提供上下文:
import timeit
timeit.Timer('a + b', 'from TestContext import *')
Run Code Online (Sandbox Code Playgroud)
似乎还有其他方法可以做到这一点,因为Timer构造函数接受对象和字符串.我仍然有兴趣学习如何做到这一点,因为a)它有其他潜在的应用; 和b)我不确定如何使用Timer构造函数的对象; 在某些情况下,这样做可能不如这种做法合适.
我已经意识到,示例代码与运行时间测试实际并不起作用,因为import *只能在模块级,并在其中执行该语句的上下文是一个的功能中testit的模块.换句话说,执行该代码时使用的全局字典是__main__,因为我在交互式shell中编写代码时就是这样.因此,解决这个问题的理由有点拙劣,但它仍然是一个有效的问题.
我发现在第一组示例中运行的代码具有不良影响,即新创建的模块代码执行的命名空间是声明它的模块,而不是 它自己的模块.这就像奇怪的方式,并可能导致各种意想不到的响尾蛇的粗略.所以我很确定这不是这种事情要做的事情,如果它实际上是Guido发光的东西.
从一个不在python的包含路径中的文件中动态加载模块的类似但略微不同的情况很容易实现imp.load_source('NewModuleName', 'path/to/module/module_to_load.py').这会将模块加载到sys.modules.然而,这并没有真正回答我的问题,因为如果你在没有文件系统的嵌入式平台上运行python 会怎么样?
我现在正在与一个相当大的信息过载案件作斗争,所以我可能会弄错,但imp模块中似乎没有任何东西可以做到这一点.
但问题本质上就是如何设置对象的全局(即模块)上下文.也许我应该更具体地问一下?在更大的范围内,如何让Python在将对象转换为给定模块的同时执行此操作?
嗯,我可以告诉你的一件事是,该timeit函数实际上使用模块的全局变量执行其代码。所以在你的例子中,你可以写
import timeit
timeit.a = 1
timeit.b = 2
timeit.Timer('a + b').timeit()
Run Code Online (Sandbox Code Playgroud)
它会起作用的。但这并不能解决动态定义模块的更普遍的问题。
关于模块定义问题,这绝对是可能的,我认为您已经偶然发现了最好的方法。作为参考,Python 导入模块时发生的事情的要点基本上如下:
module = imp.new_module(name)
execfile(file, module.__dict__)
Run Code Online (Sandbox Code Playgroud)
这与您所做的事情相同,只是您从现有字典而不是文件加载模块的内容。(我不知道文档字符串之间有什么区别types.ModuleType,imp.new_module所以你可能可以互换使用它们)你所做的有点类似于编写你自己的导入器,当你这样做时,你肯定会弄乱和sys.modules。
顺便说一句,即使你的import *东西在函数中是合法的,你可能仍然会遇到问题,因为奇怪的是,你传递给的语句Timer似乎无法识别它自己的局部变量。extract_context()我通过名称(这是我编写的函数)调用了一些 Python voodoo来设置a并b在本地范围内运行
print timeit.Timer('print locals(); a + b', 'sys.modules["__main__"].extract_context()').timeit()
Run Code Online (Sandbox Code Playgroud)
果然,打印输出locals()包含a和b:
{'a': 1, 'b': 2, '_timer': <built-in function time>, '_it': repeat(None, 999999), '_t0': 1277378305.3572791, '_i': None}
Run Code Online (Sandbox Code Playgroud)
但它仍然抱怨NameError: global name 'a' is not defined。诡异的。
| 归档时间: |
|
| 查看次数: |
12021 次 |
| 最近记录: |