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

Правильный способ перезагрузки модуля python с консоли

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

>>> from project.model.user import *
>>> reload(user)

но я получаю:

>>>NameError: name 'user' is not defined

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

Спасибо.

4b9b3361

Ответ 1

Как и было задано, самое лучшее, что вы можете сделать, это

>>> from project.models.user import *
>>> import project # get module reference for reload
>>> reload(project.models.user) # reload step 1
>>> from project.models.user import * # reload step 2

было бы лучше и чище, если бы вы использовали пользовательский модуль напрямую, вместо того, чтобы делать import * (что почти никогда не подходит для этого). Тогда это будет просто

>>> from project.models import user
>>> reload(user)

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

Мое подозрение (подкрепленное предыдущим опытом с людьми, задающими похожие вопросы) заключается в том, что вы тестируете свой модуль. Есть много способов протестировать модуль, и сделать это вручную в интерактивном интерпретаторе - один из худших способов. Сохраните одну из ваших сессий в файл и используйте doctest для быстрого исправления. В качестве альтернативы напишите его как программу и используйте python -i. Единственное действительно замечательное решение, однако, использует модуль unittest.

Если это не так, надеюсь, что-то лучше, не хуже. На самом деле нет хорошего использования reload (фактически, оно удалено в 3.x). Это не работает эффективно - вы можете перезагрузить модуль, но оставить остатки от предыдущих версий. Он даже не работает на всех типах модулей. Модули расширения не будут перезагружаться должным образом, а иногда даже прерываться при перезагрузке.

Контекст использования этого в интерактивном интерпретаторе не оставляет много выбора относительно того, что вы делаете, и каково будет самое лучшее решение. Вне этого иногда люди использовали reload() для реализации плагинов и т.д. Это в лучшем случае опасно и часто может быть сделано по-другому, используя либо exec (ах, на территорию зла, в которой мы оказались), либо отдельный процесс.

Ответ 2

К сожалению, вы должны использовать:

>>> from project.model import user
>>> reload(user)

Я не знаю, что у меня над головой что-то, что автоматически перезагрузит модули в интерактивном приглашении... Но я не вижу причин, по которым не должно существовать (на самом деле, это было бы не слишком сложно для реализации, либо...)

Теперь вы можете сделать что-то вроде этого:

from types import ModuleType
import sys
_reload_builtin = reload
def reload(thing):
    if isinstance(thing, ModuleType):
        _reload_builtin(thing)
    elif hasattr(thing, '__module__') and thing.__module__:
        module = sys.modules[thing.__module__]
        _reload_builtin(module)
    else:
        raise TypeError, "reload() argument must be a module or have an __module__"

Ответ 3

Вы не можете эффективно использовать reload().

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

Python 3 полностью удалил функцию reload().

Ответ 4

IPython может перезагружать модули перед выполнением каждой новой строки:

%load_ext autoreload
%autoreload 2

Где %autoreload 2 перезагружает "все модули (кроме тех, которые исключены% aimport) каждый раз перед выполнением введенного кода Python."

Смотрите документы:

Ответ 5

Для python3 перезагрузка была перенесена в модуль imp. вы можете использовать imp.reload(). Вы можете ссылаться на этот пост.

>>> import imp
>>> import project # get module reference for reload
>>> imp.reload(project.models.user) # reload step 1
>>> from project.models.user import * # reload step 2