При разработке большого проекта (разбитого на несколько файлов и папок) на Python с помощью IPython я столкнулся с проблемой кэшированных импортированных модулей.Предотвращение кэширования импортированных модулей Python
Проблема заключается в том, что инструкции import module
считывают модуль только один раз, даже если этот модуль изменился! Поэтому каждый раз, когда я что-то меняю в своем пакете, я должен выйти и перезапустить IPython. Болезненные.
Есть ли способ принудительно перезагрузить некоторые модули? Или, лучше, как-то помешать Python кэшировать их?
Я пробовал несколько подходов, но никто не работает. В частности, я сталкиваюсь с действительно, действительно странными ошибками, например, некоторыми модулями или переменными, таинственно становясь равными None
...
Единственный разумный ресурс, который я нашел, - Reloading Python modules, от pyunit, но я его не проверял. Мне хотелось бы что-то в этом роде.
Хорошей альтернативой было бы перезапустить IPython или как-либо перезапустить интерпретатор Python.
Итак, если вы разрабатываете в Python, какое решение вы нашли для этой проблемы?
Редактировать
Чтобы сделать вещи ясно: очевидно, я понимаю, что некоторые старые переменные в зависимости от предыдущего состояния модуля может остаться. Это прекрасно. Почему в Python так сложно заставить перезагрузить модуль без каких-либо странных ошибок?
Более конкретно, если у меня есть весь мой модуль в один файл module.py
то следующие прекрасно работает:
import sys
try:
del sys.modules['module']
except AttributeError:
pass
import module
obj = module.my_class()
Этот кусок кода работает прекрасно, и я могу развиваться, не выходя из IPython в течение нескольких месяцев.
Однако всякий раз, когда мой модуль состоит из нескольких подмодулей, ад:
import os
for mod in ['module.submod1', 'module.submod2']:
try:
del sys.module[mod]
except AttributeError:
pass
# sometimes this works, sometimes not. WHY?
Почему так различны для Python, есть ли у меня мой модуль в один большой файл или в нескольких подмодулей? Почему этот подход не работает?
Это на самом деле довольно популярный вопрос; всплывают каждый месяц. Текущий консенсус заключается в том, чтобы перезапустить вашего переводчика, как отметил Майк. –
Во-первых, я не понимаю, почему вы подавляете _AttributeError_. Просто нет способа 'del sys.modules [mod]' будет поднимать AttributeError ... кроме если вы отскакиваете 'sys' чем-то, кроме встроенного sys-модуля. Может быть просто, что во втором коде у вас есть 'sys.module' (который _will_ поднимает AttributeError с нормальным sys), а в первом вы имеете' sys.modules'? :-P – Veky