Шаг 188.
Python: сборник рецептов.
Модули и пакеты. Перезагрузка модулей

    На этом шаге мы рассмотрим особенности такой перезагрузки.

Задача

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

Решение

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




Предыдущий шаг Содержание Следующий шаг