Я работаю над pypreprocessor , который является препроцессором, который принимает директивы в стиле c, и я смог заставить его работать как традиционный препроцессор (он самопотребляет и выполняет постобработанный код на the-fly) за исключением того, что он нарушает импорт библиотеки.
Проблема: препроцессор запускает файл, обрабатывает его, выводит во временный файл и выполняет exec () временный файл. Импортируемые библиотеки необходимо обрабатывать немного по-другому, поскольку они не выполняются, а загружаются и становятся доступными для модуля вызывающей стороны.
Что мне нужно сделать, это: прервать импорт (поскольку препроцессор выполняется в середине импорта), загрузить постобработанный код как tempModule и заменить исходный импорт на tempModule, чтобы обмануть вызывая скрипт с импортом, полагая, что tempModule является исходным модулем.
Я искал везде и до сих пор, и у меня нет решения.
Этот вопрос переполнения стека наиболее близок к тому, что я видел до сих пор:
Переопределить пространство имен в Python
Вот что у меня есть.
# Remove the bytecode file created by the first import
os.remove(moduleName + '.pyc')
# Remove the first import
del sys.modules[moduleName]
# Import the postprocessed module
tmpModule = __import__(tmpModuleName)
# Set first module's reference to point to the preprocessed module
sys.modules[moduleName] = tmpModule
moduleName - это имя исходного модуля, а tmpModuleName - имя файла кода после обработки.
Странно то, что это решение по-прежнему работает совершенно нормально, как будто первый модуль завершен нормально загруженным; если вы не удалите последнюю строку, вы получите ошибку «модуль не найден».
Надеюсь, кто-то в Stack Overflow знает об импорте намного больше, чем я, потому что этот меня озадачил.
Примечание: я только награду решение, или, если это невозможно в Python; лучшее, самое подробное объяснение, почему это не невозможно.
Обновление: для всех, кто заинтересован, вот рабочий код.
if imp.lock_held() is True:
del sys.modules[moduleName]
sys.modules[tmpModuleName] = __import__(tmpModuleName)
sys.modules[moduleName] = __import__(tmpModuleName)
Часть 'imp.lock_held' определяет, загружается ли модуль как библиотека. Следующие строки делают все остальное.