Перезагрузка подмодулей в 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() (хотя она не выполняет глубокую перезагрузку, как указал Джон Сальватье в комментариях).

Ответ 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.