gpt4 book ai didi

python - 动态模块创建

转载 作者:太空狗 更新时间:2023-10-29 17:51:33 26 4
gpt4 key购买 nike

我想从字典中动态创建一个模块,我想知道向 sys.modules 添加一个元素是否真的是最好的方法。 EG

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/EUREKA:

  1. 我意识到与运行时序测试相关的示例代码实际上不会工作,因为 import * 仅在模块 级别工作,并且执行该语句的上下文是 testit 模块中的 function 的上下文。换句话说,执行该代码时使用的全局字典是 __main__ 的字典,因为那是我在交互式 shell 中编写代码时所在的位置。因此,解决这个问题的理由有点拙劣,但这仍然是一个有效的问题。

  2. 我发现在第一组示例中运行的代码会产生不良影响,即新创建的模块代码在其中执行的命名空间是声明 不是 它自己的模块。这有点奇怪,可能会导致各种意想不到的响尾蛇粗略。所以我很确定这不是应该如何完成这类事情,如果它实际上是 Guido 所照耀的东西的话。

  3. 使用 imp.load_source('NewModuleName', 'path/to/module/module_to_load.py')。这会将模块加载到 sys.modules 中。然而,这并没有真正回答我的问题,因为真的,如果你在 embedded platform with no filesystem 上运行 python 会怎样? ?

目前我正在与相当大的信息过载情况作斗争,所以我可能会弄错,但 imp 模块中似乎没有任何东西可以做到这一点。

但从本质上讲,此时的问题是如何为对象设置全局(即模块)上下文。也许我应该更具体地问一下?在更大范围内,如何让 Python 在将对象硬塞进给定模块时执行此操作?

最佳答案

嗯,我可以告诉你的一件事是 timeit 函数实际上使用模块的全局变量执行它的代码。所以在你的例子中,你可以写

import timeit
timeit.a = 1
timeit.b = 2
timeit.Timer('a + b').timeit()

它会起作用的。但这并没有解决您动态定义模块的更普遍的问题。

关于模块定义问题,这绝对是可能的,我认为您已经偶然发现了几乎最好的方法。作为引用,Python 导入模块时发生的事情的要点基本上如下:

module = imp.new_module(name)
execfile(file, module.__dict__)

除了从现有字典而不是文件中加载模块的内容外,这与您所做的类似。 (除了文档字符串,我不知道 types.ModuleTypeimp.new_module 之间有什么区别,所以你可以互换使用它们)你正在做的是有点类似于编写您自己的导入程序,当您这样做时,您肯定会弄乱 sys.modules

顺便说一句,即使您的 import * 在函数中是合法的,您可能仍然会遇到问题,因为奇怪的是,您传递给 Timer 的语句并没有' 似乎能识别它自己的局部变量。我调用了一些名为 extract_context()(这是我编写的函数)的 Python 巫术来在本地设置 ab范围和运行

print timeit.Timer('print locals(); a + b', 'sys.modules["__main__"].extract_context()').timeit()

果然,locals() 的打印输出包括ab:

{'a': 1, 'b': 2, '_timer': <built-in function time>, '_it': repeat(None, 999999), '_t0': 1277378305.3572791, '_i': None}

但它仍然报错NameError: global name 'a' is not defined。很奇怪。

关于python - 动态模块创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2931950/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com