Как выгрузить (перезагрузить) модуль Python?

Если одна программа прослушивается на порту, я не считаю, что другой может. Как правило, нижние порты зарезервированы для определенных сервисов, таких как HTTP на порту 80. Если вам нужен случайный порт, вы должны создать один выше 1024. Список наиболее часто используемых портов смотрите здесь: http: //en.wikipedia .org / wiki / List_of_TCP_and_UDP_port_numbers

изменить: исправлено из комментария ниже

729
задан Mark Harrison 14 April 2015 в 07:56
поделиться

6 ответов

Можно перезагрузить модуль, когда он был уже импортирован при помощи reload встроенная функция:

from importlib import reload  # Python 3.4+ only.
import foo

while True:
    # Do some things.
    if is_changed(foo):
        foo = reload(foo)

В Python 3, reload был перемещен в imp модуль. В 3,4, imp удерживался от использования в пользу [1 113] importlib , и reload был добавлен к последнему. При предназначении 3 или позже, или ссылка соответствующий модуль при вызове reload или импорт это.

я думаю, что это - то, что Вы хотите. Веб-серверы как сервер разработки Django используют это так, чтобы Вы видели эффекты своих изменений кода, не перезапуская сам серверный процесс.

Для заключения в кавычки из документов:

Python modules’ код перекомпилирован и повторно выполняемый код уровня модуля, определив новый набор объектов, которые связываются с именами в module’s словаре. init функция дополнительных модулей не вызвана во второй раз. Как со всеми другими объектами в Python только исправлены старые объекты после того, как их подсчеты ссылок опускаются до нуля. Имена в пространстве имен модуля обновляются для указания на любые новые или измененные объекты. Другие ссылки на старые объекты (такие как имена, внешние к модулю), не являются восстановлением для обращения к новым объектам и должны быть обновлены в каждом пространстве имен, где они происходят, если это желаемо.

, Поскольку Вы отметили в своем вопросе, необходимо будет восстановить Foo объекты, если Foo класс находится в foo модуль.

700
ответ дан Tom Leys 14 April 2015 в 07:56
поделиться
  • 1
    Я понимаю Ваше чувство так прямо сейчас. I' m на более чем 10 часах попытки заставить этот sht работать... it' s удивительный, что эта проблема имеет миллион различных решений и everyone' s решение отличается и все же я все еще can' t находят решение. – Terence Chow 8 August 2013 в 05:21

reload(module), но только если это абсолютно автономно. Если что-либо еще будет иметь ссылку на модуль (или любой объект, принадлежащий модулю), то Вы получите тонкие и любопытные ошибки, вызванные старым кодом, бродящим вокруг дольше, чем Вы ожидали, и вещи как isinstance не работа через различные версии того же кода.

, Если у Вас есть односторонние зависимости, необходимо также перезагрузить все модули, которые зависят от перезагруженный модуль для избавлений от всех ссылок на старый код. И затем модули перезагрузки, которые зависят от перезагруженных модулей, рекурсивно.

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

единственный способ сделать это в этом случае состоит в том, чтобы взломать sys.modules, который отчасти не поддерживается. Необходимо было бы пройти и удалить каждый sys.modules запись, Вы хотели быть перезагруженными на следующем импорте, и также удалить записи, значения которых None, чтобы заниматься проблемой реализации, чтобы сделать с кэшированием неудавшегося относительного импорта. Это не ужасно хорошо, но, пока у Вас есть полностью автономный набор зависимостей, который не оставляет ссылки вне его кодовой базы, это осуществимо.

, вероятно, лучше перезапустить сервер.:-)

66
ответ дан jdloft 14 April 2015 в 07:56
поделиться
  • 1
    +1 @Cody Gray - в целом я соглашаюсь, просто заключал в кавычки то, что MSDN говорит об этом. – YetAnotherUser 21 May 2011 в 15:16

Может быть особенно трудно удалить модуль, если это не чистый Python.

Вот некоторая информация от: , Как я действительно удаляю импортированный модуль?

можно использовать sys.getrefcount () для обнаружения фактического количества ссылок.

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3

Числа, больше, чем 3, указывают, что будет трудно избавиться от модуля. "Пустое" собственной разработки (содержащий ничто) модуль должен быть собран "мусор", после

>>> del sys.modules["empty"]
>>> del empty

, поскольку третья ссылка является артефактом getrefcount () функция.

88
ответ дан Honest Abe 29 September 2019 в 02:22
поделиться

В Python 3.0–3.3 вы должны использовать: imp.reload (module)

BDFL ответил на этот вопрос.

Однако imp устарел в версии 3.4 в пользу importlib (спасибо @Stefan! ).

Я думаю ], поэтому теперь вы должны использовать importlib.reload (module) , хотя я не уверен.

245
ответ дан 22 November 2019 в 21:26
поделиться

Для тех, кто, как я, хочет выгрузить все модули (при работе в интерпретаторе Python под Emacs ):

   for mod in sys.modules.values():
      reload(mod)

Дополнительная информация находится в Перезагрузка модулей Python .

7
ответ дан 22 November 2019 в 21:26
поделиться
if 'myModule' in sys.modules:  
    del sys.modules["myModule"]
61
ответ дан 22 November 2019 в 21:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: