【问题标题】:How to generate a module object from a code object in Python如何从 Python 中的代码对象生成模块对象
【发布时间】:2011-01-19 21:05:32
【问题描述】:

鉴于我有一个模块的代码对象,如何获取对应的模块对象?

看起来moduleNames = {}; exec code in moduleNames 做了一些非常接近我想要的事情。它将模块中声明的全局变量返回到字典中。但是如果我想要实际的模块对象,我该如何获取呢?

编辑: 看起来您可以滚动自己的模块对象。模块类型没有方便地记录,但您可以执行以下操作:

import sys
module = sys.__class__
del sys
foo = module('foo', 'Doc string')
foo.__file__ = 'foo.pyc'
exec code in foo.__dict__

【问题讨论】:

  • 模块类型的首选访问点是types.ModuleType

标签: python bytecode


【解决方案1】:

正如评论已经指出的那样,在今天的 Python 中,实例化没有内置名称的类型的首选方法是调用通过标准库中的 types 模块获得的类型:

>>> import types
>>> m = types.ModuleType('m', 'The m module')

请注意,这不会自动将新模块插入sys.modules

>>> import sys
>>> sys.modules['m']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'm'

这是您必须手动执行的任务:

>>> sys.modules['m'] = m
>>> sys.modules['m']
<module 'm' (built-in)>

这可能很重要,因为模块的代码对象通常模块添加到sys.modules 之后执行——例如,此类代码引用sys.modules[__name__] 是完全正确的,并且如果您忘记了这一步,将会失败 (KeyError)。 这一步之后,将m.__file__ 设置为您在编辑中已有的,

>>> code = compile("a=23", "m.py", "exec")
>>> exec code in m.__dict__
>>> m.a
23

(或 Python 3 等价物,其中 exec 是一个函数,如果 Python 3 是您正在使用的,当然;-) 是正确的(当然,您通常会通过更微妙的方式获得代码对象而不是编译一个字符串,但这对你的问题并不重要;-)。

在旧版本的 Python 中,您可能会在开始时使用 new 模块而不是 types 模块来创建新的模块对象,但 new 自 Python 2.6 起已被弃用,并在 Python 3 中被删除。

【讨论】:

    猜你喜欢
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 2022-08-24
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多