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

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

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

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

import sys
module = sys.__class__
del sys
foo = module('foo', 'Doc string')
foo.__file__ = 'foo.pyc'
exec code in foo.__dict__
12
задан Tac-Tics 22 February 2010 в 23:56
поделиться

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.

21
ответ дан 2 December 2019 в 07:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: