Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

А

from module import *

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

reload(sys.modules['module'])

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

Ответ 4

Более чистый ответ - это сочетание хорошего ответа Катскула и использования Охадом Коэном 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

Ответ 5

Я нашел другой способ перезагрузки модуля при импорте, например:

from directory.module import my_func

Приятно знать, как вообще импортируются модули. Модуль ищется в словаре sys.modules. Если он уже существует в sys.modules - модуль больше не будет импортирован.

Поэтому, если мы хотим перезагрузить наш модуль, мы можем просто удалить его из sys.modules и снова импортировать:

import sys
from directory.module import my_func
my_func('spam')
# output: 'spam'

# here I have edited my_func in module.py

my_func('spam') # same result as above
#output: 'spam'


del sys.modules[my_func.__module__]
from directory.module import my_func

my_func('spam') # new result
#output: 'spam spam spam spam spam'

Если вы хотите получить перезагруженный модуль при запуске всего сценария, вы можете использовать обработчик исключений:

try:
    del sys.modules[my_func.__module__]

except NameError as e:
    print("""Can't remove module that haven't been imported.
    Error: {}""".format(e))

from utils.module import my_func

..........
# code of the script here

Ответ 6

При импорте с использованием 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

Ответ 7

import re

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

Ответ 8

для Python 3.7:

from importlib import reload #import function "reload"
import YourModule #import your any modules
reload(YourModule) #reload your module

Функция перезагрузки может быть вызвана из вашей собственной функции

def yourFunc():
   reload(YourModule)