модуль перезагрузки, который был импортирован в другой модуль

Посмотрим правде в глаза, все дело в перезагрузке кода python после его изменения – беспорядок. Я немного сообразил, что вызов import <module> в интерпретаторе лучше, чем from <module> import <class/function> , потому что тогда я могу вызвать reload(module) чтобы получить обновленный код.

Но сейчас у меня есть более сложные проблемы. Поэтому у меня есть этот файл, module1.py, а наверху он говорит:

 from module2 import <class1>, <function1>, etc. 

И затем я иду и меняю код внутри модуля2. Оказывается, что reload(module1) вызова reload(module1) не перезагружает код, измененный в модуле2, хотя код из модуля2 импортируется в верхней части модуля1. Есть ли способ перезагрузить все без перезапуска интерпретатора?

Прежде чем кто-нибудь узнает о моем стиле, я просто скажу:

  1. Я только вызываю reload из интерпретатора, никогда в активном коде. Этот вопрос касается того, когда я тестирую новый код.
  2. Я никогда не звоню из <module> import * , я знаю, что уничтожает читаемость

6 Solutions collect form web for “модуль перезагрузки, который был импортирован в другой модуль”

Посмотрите на IPython. Он имеет расширение автозагрузки, которое автоматически перезагружает модули во время сеанса интерпретатора перед вызовом функций внутри. Я приведу пример с целевой страницы:

 In [1]: %load_ext autoreload In [2]: %autoreload 2 In [3]: from foo import some_function In [4]: some_function() Out[4]: 42 In [5]: # open foo.py in an editor and change some_function to return 43 In [6]: some_function() Out[6]: 43 

Чтобы перезагрузить модуль, вы должны использовать reload , и вы должны использовать его в модуле, который хотите перезагрузить. Перезагрузка модуля не рекурсивно перезагружает все модули, импортированные этим модулем. Он просто перезагружает этот модуль.

Когда модуль импортируется, ссылка на него сохраняется, а затем импорт этого модуля повторно использует уже импортированную, уже сохраненную версию. Когда вы перезагружаете module1 , он повторно запускает from module2 import ... но он просто повторно использует уже импортированную версию module2 без перезагрузки.

Единственный способ исправить это – изменить код, чтобы он import module2 вместо (или в дополнение к) from module2 import ... Вы не можете перезагрузить модуль, если только сам модуль не был импортирован и не привязан к имени (т. import module оператором import module , а не только from module import stuff оператора from module import stuff ).

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

 >>> import module >>> from module import x >>> x 2 # Change module code here, changing x to 3 >>> reload(module) >>> from module import x >>> x 3 

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

Хорошо, я не уверен, что квалифицируется как ответ без изменения кода, но … по крайней мере, это не связано с изменением module1 .

Вы можете использовать некоторый класс оболочки модуля, который сохраняет загруженные модули до и после загрузки модуля1 и предоставляет метод reload , что-то вроде этого:

 import sys class Reloader(object): def __init__(self, modulename): before = sys.modules.keys() __import__(modulename) after = sys.modules.keys() names = list(set(after) - set(before)) self._toreload = [sys.modules[name] for name in names] def do_reload(self): for i in self._toreload: reload(i) 

Затем загрузите модуль 1 с помощью:

 reloader = Reloader('module1') 

Подтвердите, что вы можете изменить module2 и перезагрузить его в интерпретаторе с помощью:

 reloader.do_reload() 

Вместо того, чтобы улучшаться при перезагрузке модулей, вы могли бы лучше перезапустить интерпретатор. Например, вы можете поместить свой код установки в свой собственный файл, а затем запустить его следующим образом:

 $ python -i setup.py >>> 

Это запустит setup.py, а затем оставит вас в интерактивном приглашении. Или, вместо того, чтобы выполнять большую часть работы в интерактивной подсказке, напишите автоматизированные тесты, которые сделают вашу работу за вас.

Вы правы, перезагрузка модулей в Python – беспорядок. Семантика языка затрудняет изменение кода во время работы процесса. Научитесь не перегружать модули, вы будете счастливее.

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

 >>> reload(module2) >>> module1.class1 = module2.class1 

Теперь объект class1 внутри модуля1 относится к перезагруженной версии из модуля2.

Вот рекурсивная функция перезагрузки, которую вы можете использовать (кредит для @Matthew): https://stackoverflow.com/a/17194836/1020625

    Python - лучший язык программирования в мире.