На этом шаге мы рассмотрим особенности такой перезагрузки.
Вы хотите перезагрузить уже загруженный модуль, потому что внесли изменения в его исходный код.
Чтобы перезагрузить ранее загруженный модуль, используйте imp.reload(). Например:
>>> import spam >>> import imp >>> imp.reload(spam) <module 'spam' from './spam.py'> >>>
Перезагрузка модуля часто используется во время отладки и разработки, но в общем случае ее небезопасно применять в продакшне, поскольку она не всегда работает так, как вы ожидаете.
"Под капотом" операция reload() стирает содержимое словаря модуля и обновляет его, повторно выполняя исходный код модуля. Идентичность самого объекта модуля остается без изменений. Так что эта операция обновляет модуль в программе везде, где он импортирован.
Однако reload() не обновляет определения, которые были импортированы с помощью таких инструкций, как from module import name. Для примера рассмотрим такой код:
# spam.py def bar(): print('bar') def grok(): print('grok')
Теперь начнем интерактивный сеанс:
>>> import spam >>> from spam import grok >>> spam.bar() bar >>> grok() grok >>>
Не покидая Python, отредактируйте исходный код spam.py так, чтобы функция grok() стала такой:
def grok(): print('New grok')
Теперь вернитесь к интерактивному сеансу, выполните перезагрузку и попробуйте провести такой эксперимент:
>>> import imp >>> imp.reload(spam) <module 'spam' from './spam.py'> >>> spam.bar() bar >>> grok() # Обратите внимание на старый вывод grok >>> spam.grok() # Обратите внимание на новый вывод New grok >>>
В этом примере вы видите, что загружены две версии grok(). Обычно это не то, чего вы хотите, и такие фокусы могут привести к очень большой головной боли.
По этой причине перезагрузки модулей в продакшне стоит избегать. Оставьте этот прием для отладки или интерактивных сеансов, где вы экспериментируете и пробуете разные штуки.
На следующем шаге мы рассмотрим создание каталога или zip-архива, запускаемых как основной скрипт.