Перезагрузка подмодулей в IPython
В настоящее время я работаю над проектом python, который содержит вспомогательные модули и использует numpy/scipy. Ipython используется как интерактивная консоль. К сожалению, я не очень доволен рабочим процессом, который я использую прямо сейчас, я был бы признателен за некоторые советы.
В IPython инфраструктура загружается простой командой import
. Однако часто бывает необходимо изменить код в одном из подмодулей структуры. На данный момент модель уже загружена, и я использую IPython для взаимодействия с ней.
Теперь структура содержит множество модулей, которые зависят друг от друга, то есть при первоначальной загрузке структуры основной модуль импортирует и настраивает подмодули. Изменения в коде выполняются только в том случае, если модуль перезагружается с помощью reload(main_mod.sub_mod)
. Это громоздко, поскольку мне нужно перезагрузить все измененные модули индивидуально, используя полный путь. Было бы очень удобно, если бы reload(main_module)
также перезагрузил все вспомогательные модули, но без перезагрузки numpy/scipy.
Ответы
Ответ 1
IPython поставляется с некоторой магией автоматической перезагрузки:
%load_ext autoreload
%autoreload 2
Он будет перезагружать все измененные модули каждый раз перед выполнением новой строки. То, как это работает, немного отличается от dreload
. Применяются некоторые предостережения, типа %autoreload?
чтобы увидеть, что может пойти не так.
Если вы хотите всегда включать эти параметры, измените файл конфигурации IPython ~/.ipython/profile_default/ipython_config.py
[1] и добавьте:
c.InteractiveShellApp.extensions = ['autoreload']
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
Кредит @Kos через комментарий ниже.
[1] Если у вас нет файла ~/.ipython/profile_default/ipython_config.py
, вам нужно ipython profile create
вызвать ipython profile create
. Или файл может быть расположен в $IPYTHONDIR
.
Ответ 2
В IPython 0.12 (и, возможно, ранее) вы можете использовать это:
%load_ext autoreload
%autoreload 2
Это по сути то же самое, что и ответ pv., за исключением того, что расширение было переименовано и теперь загружено с помощью %load_ext
.
Ответ 3
IPython предлагает dreload()
, чтобы рекурсивно перезагрузить все подмодули. Лично я предпочитаю использовать магическую команду %run()
(хотя она не выполняет глубокую перезагрузку, как указал Джон Сальватье в комментариях).
Ответ 4
По какой-то причине ни %autoreload
, ни dreload
не работают, если вы импортируете код из одного ноутбука в другой. Только простой Python reload
работает:
reload(module)
На основе [1].
Ответ 5
Как насчет этого:
import inspect
# needs to be primed with an empty set for loaded
def recursively_reload_all_submodules(module, loaded=None):
for name in dir(module):
member = getattr(module, name)
if inspect.ismodule(member) and member not in loaded:
recursively_reload_all_submodules(member, loaded)
loaded.add(module)
reload(module)
import mymodule
recursively_reload_all_submodules(mymodule, set())
Это должно эффективно перезагрузить все дерево модулей и подмодулей, которые вы ему даете. Вы также можете поместить эту функцию в свой .ipythonrc(я думаю), чтобы он загружался каждый раз при запуске интерпретатора.
Ответ 6
http://shawnleezx.github.io/blog/2015/08/03/some-notes-on-ipython-startup-script/
Чтобы не вводить эти магические функции снова и снова, их можно поместить в сценарий запуска ipython (назовите его суффиксом.py в.ipython/profile_default/startup. Все сценарии python в этой папке будут загружены в соответствии с лексическим порядком), что выглядит следующим образом:
from IPython import get_ipython
ipython = get_ipython()
ipython.magic("pylab")
ipython.magic("load_ext autoreload")
ipython.magic("autoreload 2")
Ответ 7
Другая опция:
$ cat << EOF > ~/.ipython/profile_default/startup/50-autoreload.ipy
%load_ext autoreload
%autoreload 2
EOF
Проверено на ipython и ipython3 v5.1.0 на Ubuntu 14.04.
Ответ 8
Моя стандартная практика для перезагрузки - комбинировать оба метода после первого открытия IPython
:
from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2
Загрузка модулей перед этим приведет к тому, что они не будут перезагружены даже при ручной reload(module_name)
. Я все еще очень редко получаю необъяснимые проблемы с методами класса, не перезагружающими, что я еще не изучал.
Ответ 9
На ноутбуках Jupyter на Anaconda, делая это:
%load_ext autoreload
%autoreload 2
появилось сообщение:
Расширение автозагрузки уже загружено. Чтобы перезагрузить его, используйте: %reload_ext autoreload
Похоже, это предпочтительнее:
%reload_ext autoreload
%autoreload 2
Информация о версии:
Версия сервера ноутбука 5.0.0 и работает: Python 3.6.2 | Anaconda, Inc. | (по умолчанию, 20 сентября 2017, 13:35:58) [MSC v.1900 32 бит (Intel)]
Ответ 10
Модуль с именем importlib
позволяет получить доступ к внутренним importlib
импорта. Особенно, это обеспечивает функцию importlib.reload()
:
import importlib
importlib.reload(my_module)
В отличие от %autoreload
, importlib.reload()
также сбрасывает глобальные переменные, установленные в модуле. В большинстве случаев это то, что вы хотите.
importlib
доступен только с Python 3.1. Для более старой версии вы должны использовать модуль imp
.