Как перезагрузить модуль python, импортированный с помощью " from module import *`

я видела в это полезный Q & A что можно использовать reload(whatever_module) или, в Python 3, imp.reload(whatever_module).

мой вопрос в том, что если бы я сказал from whatever_module import * импортировать? Тогда у меня нет whatever_module ссылаться, когда я использую reload(). Вы, ребята, собираетесь кричать на меня за то, что я бросил целый модуль в глобальное пространство имен? :)

6 ответов


Я согласен с "Не делайте этого вообще" консенсус, но...

правильный ответ:

import X
reload(X)
from X import Y  # or * for that matter

никогда не используйте import *; Это разрушает читаемость.

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


A

from module import *

принимает все "экспортированные" объекты из module и привязывает их к именам на уровне модуля (или независимо от того, что ваша область была уровнем). Вы можете перезагрузить модуль, как:

reload(sys.modules['module'])

но это не принесет вам никакой пользы: имена, независимо от того, какой уровень был у вас, все еще указывают на старые объекты.


при импорте с помощью from whatever_module import whatever, whatever считается частью модуля импорта, поэтому для его перезагрузки - вы должны перезагрузить свой модуль. Но просто перезагрузив свой модуль, вы все равно получите старый whatever - от уже-импортные whatever_module, поэтому вам нужно перезагрузить (whatever_module), а затем перезагрузить модуль:

# reload(whatever_module), if you imported it
reload(sys.modules['whatever_module'])
reload(sys.modules[__name__])

если вы используете from whatever_module import whatever вы также можете рассмотреть

whatever=reload(sys.modules['whatever_module']).whatever

или

whatever=reload(whatever_module).whatever

более чистый ответ-это сочетание хорошего ответа Catskul и использования Охад Коэн sys.module и прямое переопределение:

import sys
Y = reload(sys.module["X"]).Y  # reload() returns the new module

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

интересным моментом здесь является то, что from X import Y не добавлять X в пространстве имен, но добавляет модуль X в список известных модулей (sys.modules), что позволяет перезагрузить модуль (и получить доступ к его новому содержимому).

в целом, если несколько импортированных символов необходимо обновить, то удобнее импортировать их следующим образом:

import sys
reload(sys.module["X"])  # No X symbol created!
from X import Y, Z, T

import re

for mod in sys.modules.values():
    if re.search('name', str(mod)):
        reload(mod)