5

Перезагрузка сабмодулей в IPython

16

Я работаю над проектом на Python, который содержит подмодули и использует библиотеки NumPy и SciPy. В качестве интерактивной консоли я использую IPython. Однако меня не устраивает текущий рабочий процесс, и я хотел бы получить советы по улучшению.

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

Проблема в том, что фреймворк содержит множество взаимосвязанных модулей, т.е. когда фреймворк сначала загружается, главный модуль импортирует и настраивает подмодули. Изменения в коде выполняются только в том случае, если модуль перезагружается с помощью reload(main_mod.sub_mod). Этот процесс довольно утомителен, так как мне нужно перезагружать все измененные модули индивидуально, используя полный путь. Было бы очень удобно, если бы команда reload(main_module) автоматически перезагружала все подмодули, но без перезагрузки NumPy и SciPy.

Есть ли способ оптимизировать этот процесс в IPython?

5 ответ(ов)

0

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

Таким образом, все указанные магические команды будут автоматически выполняться при запуске IPython, что существенно упростит вашу работу.

0

Вот как можно перевести ваш ответ на русский язык в стиле StackOverflow:


Можно использовать следующий код для перезагрузки всех подмодулей рекурсивно:

import inspect

# Необходимо инициализировать с пустым множеством для загруженных модулей
def recursively_reload_all_submodules(module, loaded=None):
    if loaded is None:
        loaded = set()

    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)
    import importlib
    importlib.reload(module)

import mymodule
recursively_reload_all_submodules(mymodule, set())

Этот код эффективно перезагрузит все модули и подмодули, которые вы ему передадите. Вы также можете добавить эту функцию в ваш файл .ipythonrc, чтобы она загружалась каждый раз при запуске интерпретатора.

Обратите внимание, что для перезагрузки модулей рекомендуется использовать importlib.reload(), так как это стандартный способ перезагрузки модулей в Python 3.

0

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

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

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

0

Еще один вариант:

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

Проверено на ipython и ipython3 версии 5.1.0 в Ubuntu 14.04.

0

Перед импортом ваших модулей добавьте следующие строки, где первая проверяет, загружено ли расширение autoreload:

if 'autoreload' not in get_ipython().extension_manager.loaded:
    %load_ext autoreload
%autoreload 2

import sys
    .
    .
    .

Это гарантирует, что расширение autoreload будет загружено только один раз, что позволяет автоматически перезагружать измененные модули без необходимости перезапускать IPython или Jupyter-ноутбук.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь