динамическое создание модуля [дубликат]

12
задан intuited 30 May 2010 в 03:31
поделиться

1 ответ

Хм, ну одно я могу сказать, что функция 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.ModuleType и imp.new_module, кроме docstring, так что вы, вероятно, можете использовать их взаимозаменяемо) То, что вы делаете, сродни написанию собственного импортера, и когда вы это делаете, вы, конечно, можете ожидать, что будете возиться с sys.modules.

В качестве отступления, даже если бы ваш import * был законным внутри функции, у вас все равно могли бы возникнуть проблемы, потому что, как ни странно, оператор, который вы передаете в Timer, похоже, не распознает свои собственные локальные переменные. Я вызвал немного вуду в Python по имени extract_context() (это функция, которую я написал), чтобы установить a и b в локальной области видимости и запустил

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

Конечно, достаточно, распечатка locals() включала a и b:

{'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. Странно.

1
ответ дан 3 December 2019 в 00:08
поделиться
Другие вопросы по тегам:

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