Подтвердить что ты не робот

Как сгенерировать объект модуля из объекта кода в Python

Учитывая, что у меня есть объект кода для модуля, как мне получить соответствующий объект модуля?

Похоже, что moduleNames = {}; exec code in moduleNames делает что-то очень близкое к тому, что я хочу. Он возвращает глобалы, объявленные в модуле, в словарь. Но если я хочу фактический объект модуля, как его получить?

EDIT: Похоже, вы можете свернуть свой собственный объект модуля. Тип модуля удобно документировать, но вы можете сделать что-то вроде этого:

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

Ответ 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.