Повторно импортируйте модуль в Python, пока он интерактивный

384

Я знаю, что это можно сделать, но я никогда не помню, как.

Как вы можете повторно импортировать модуль в Python? Сценарий таков: я импортирую модуль в интерактивном режиме и работаю с ним, но затем я сталкиваюсь с ошибкой. Я исправляю ошибку в .py файле и затем хочу повторно импортировать исправленный модуль, не выходя из python. Как мне это сделать ?

Стефано Борини
источник
1
Возможный дубликат Как выгрузить (перезагрузить) модуль Python?
Уолтер
повторно импортировать

Ответы:

370

Это должно работать:

reload(my.module)

Из документов Python

Перезагрузите ранее импортированный модуль. Аргумент должен быть объектом модуля, поэтому он должен быть успешно импортирован ранее. Это полезно, если вы отредактировали исходный файл модуля с помощью внешнего редактора и хотите опробовать новую версию, не выходя из интерпретатора Python.

Если работает Python 3.4 и выше, то делай import importlib, потом делай importlib.reload(nameOfModule).

Не забудьте предостережения об использовании этого метода:

  • Когда модуль перезагружается, его словарь (содержащий глобальные переменные модуля) сохраняется. Переопределения имен переопределяют старые определения, поэтому это, как правило, не является проблемой, но если новая версия модуля не определяет имя, которое было определено в старой версии, старое определение не удаляется.

  • Если модуль импортирует объекты из другого модуля, используя from ... import ..., вызов reload()другого модуля не переопределяет импортированные из него объекты - одним из способов является повторное выполнение fromоператора, другой - использование importи квалифицированные names ( module.*name*).

  • Если модуль создает экземпляры класса, перезагрузка модуля, который определяет класс, не влияет на определения методов экземпляров - они продолжают использовать старое определение класса. То же самое верно для производных классов.

Бенджамин Вольвенд
источник
26
если я загружу свои модули, используя from filename import *. Как перезагрузить?
Питер Чжу
@PeterZhu для случая "from mod import fcn", объект модуля не добавляется в пространство имен. Таким образом, вам нужно явно импортировать модуль, чтобы вы могли позже перезагрузить его. import foo; from foo import bar; reload(foo)
Тед
Я попытался перезагрузить, а также волшебство автозагрузки, и я вижу, что мое изменение кода отражено в стеке сообщения об ошибке, но сама ошибка все еще кажется вне устаревшего кода (например, строка ошибки точно такая же строка, как и раньше, которую я изменил на комментарий, и комментарий явно не может вызывать ошибки). Мой модуль загружен как расширение Jupyter, может кто-нибудь знает, требует ли это другой работы? Спасибо!
Ифану
1
Если вы импортировали свою функцию как «импорт мода как имя», то вам нужно сделать следующее: «import importlib importlib.reload (name)»
Noe
Этот метод не может переопределять ссылки других модулей на перезагруженный модуль. См. Stackoverflow.com/a/61617169/2642356 для решения этой проблемы.
EZLearner
288

В Python 3 reloadбольше не является встроенной функцией.

Если вы используете Python 3.4+ , вы должны использовать reloadиз importlibбиблиотеки вместо:

import importlib
importlib.reload(some_module)

Если вы используете Python 3.2 или 3.3, вы должны:

import imp  
imp.reload(module)  

вместо. См. Http://docs.python.org/3.0/library/imp.html#imp.reload.

Если вы используете ipython, обязательно рассмотрите возможность использования autoreloadрасширения:

%load_ext autoreload
%autoreload 2
Эндрю
источник
Хотя большая часть кода Python написана на Python 2, Python 3 становится более жизнеспособным вариантом с каждым днем. Спасибо за совет!
Аарон Джонсон
40
imp.reloadустарела начиная с Python 3.4, вместо этого используйте importlib.reloadфункцию .
JFS
1
@ Андрей спасибо! Я использовал% autoreload, это замечательно, мои уже созданные объекты получили автоматически исправленную реализацию методов класса без необходимости их
повторного создания
4
Я немного опоздал, но я думаю , что это не работает , если то , что вам нужно перезарядить функцию или класс внутри модуля: если мой импорт Постулаты были from mymodule import myfunc, тогда importlib.reload(myfunc), importlib.reload(mymodule.myfunc), importlib.reload(mymodule)все дают NameError.
Puff
@Puff, смотрите мой ответ ниже о том, как повторно импортировать функцию
jss367
46

Собственно, в Python 3 модуль imp помечен как УСТАРЕВШИЙ. Ну, по крайней мере, это правда для 3.4.

Вместо reloadфункции изimportlib следует использовать модуля:

https://docs.python.org/3/library/importlib.html#importlib.reload

Но учтите, что в этой библиотеке были некоторые API-изменения с двумя последними минорными версиями.

фанки-будущее
источник
6

Если вы хотите импортировать определенную функцию или класс из модуля, вы можете сделать это:

import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function
jss367
источник
0

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

Если модуль импортирует объекты из другого модуля, используя from ... import ..., вызов reload()другого модуля не переопределяет импортированные из него объекты - одним из способов является повторное выполнение оператора from, другой - использование importи квалифицированные names ( module.*name*).

Однако при использовании __all__переменной для определения общедоступного API можно автоматически перезагрузить все общедоступные модули:

# Python >= 3.5
import importlib
import types


def walk_reload(module: types.ModuleType) -> None:
    if hasattr(module, "__all__"):
        for submodule_name in module.__all__:
            walk_reload(getattr(module, submodule_name))
    importlib.reload(module)


walk_reload(my_module)

Предостережения, отмеченные в предыдущем ответе, остаются в силе. В частности, изменение подмодуля, который не является частью общедоступного API, как описано в __all__переменной, не будет затронуто перезагрузкой с использованием этой функции. Точно так же удаление элемента субмодуля не будет отражено перезагрузкой.

skasch
источник