Перезагрузка субмодулей в IPython - PullRequest
322 голосов
/ 19 марта 2011

В настоящее время я работаю над проектом на python, который содержит подмодули и использует numpy / scipy. Ipython используется в качестве интерактивной консоли. К сожалению, я не очень доволен рабочим процессом, который я использую сейчас, я был бы признателен за некоторые советы.

В IPython инфраструктура загружается простой командой import. Однако часто бывает необходимо изменить код в одном из подмодулей фреймворка. На данный момент модель уже загружена, и я использую IPython для взаимодействия с ней.

Теперь платформа содержит много модулей, которые зависят друг от друга, то есть, когда платформа изначально загружена, основной модуль импортирует и конфигурирует подмодули. Изменения в коде выполняются только в том случае, если модуль перезагружается с использованием reload(main_mod.sub_mod). Это громоздко, так как мне нужно перезагрузить все измененные модули индивидуально, используя полный путь. Было бы очень удобно, если бы reload(main_module) также перезагрузил бы все подмодули, но без перезагрузки numpy / scipy ..

Ответы [ 10 ]

457 голосов
/ 23 марта 2011

IPython поставляется с некоторой автоматической перезагрузкой magic:

%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. Или файл может быть расположен на $IPYTHONDIR.

24 голосов
/ 07 февраля 2012

В IPython 0.12 (и, возможно, ранее) вы можете использовать это:

%load_ext autoreload
%autoreload 2

По сути, это то же самое, что и ответ pv. , за исключением того, что расширение былопереименован и теперь загружается с помощью %load_ext.

18 голосов
/ 20 марта 2011

IPython предлагает dreload() для рекурсивной перезагрузки всех подмодулей. Лично я предпочитаю использовать магическую команду %run() (хотя она не выполняет глубокую перезагрузку, как указал Джон Сальватье в комментариях).

14 голосов
/ 28 сентября 2016

По какой-то причине ни %autoreload, ни dreload не работают в ситуации, когда вы импортируете код из одной записной книжки в другую . Работает только обычный Python reload:

reload(module)

На основе [1] .

3 голосов
/ 06 июня 2018

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")
3 голосов
/ 20 марта 2011

Как насчет этого:

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

2 голосов
/ 23 ноября 2016

Другой вариант:

$ cat << EOF > ~/.ipython/profile_default/startup/50-autoreload.ipy
%load_ext autoreload
%autoreload 2
EOF

Проверено на ipython и ipython3 v5.1.0 на Ubuntu 14.04.

1 голос
/ 30 января 2019

Модуль с именем importlib позволяет получить доступ к внутренним объектам импорта. Особенно это обеспечивает функцию importlib.reload():

import importlib
importlib.reload(my_module)

В отличие от %autoreload, importlib.reload() также сбрасывает глобальные переменные, установленные в модуле. В большинстве случаев это то, что вы хотите.

importlib доступно только с Python 3.1. Для более старой версии вы должны использовать модуль imp.

1 голос
/ 24 ноября 2016

Моя стандартная практика для перезагрузки - комбинировать оба метода после первого открытия IPython:

from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2

Загрузка модулей перед этим приведет к тому, что они не будут перезагружены, даже с руководством reload(module_name). Я все еще очень редко получаю необъяснимые проблемы с методами класса, не перезагружающими, которые я еще не изучал.

0 голосов
/ 26 октября 2017

В Jupyter Notebooks на 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)]

...