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

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

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

но я получаю:

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

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

Благодарю.

6 ответов

Решение

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

>>> 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 (ах та злая территория, на которой мы находимся), или отдельный процесс.

Для 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

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

%load_ext autoreload
%autoreload 2

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

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

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

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

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

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

>>> 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__"

Начиная с Python 3.4 вы можете использовать importlib.reload(module)

>>> from importlib import reload
>>> from project.model import user
>>> reload(user)
    from test_reload import add_test

где test_reload это модуль, а add_test это функция, если вы изменили функцию add_test, конечно, вам нужно перезагрузить эту функцию. тогда вы можете сделать это:


    import imp
    imp.reload(test_reload)
    from test_reload import add_test

это обновит функцию add_test.

так что вам нужно добавить

imp.reload(test_reload)
from test_reload import add_test  --add this line in your code

Вы также можете попробовать twisted.python.rebuild.rebuild,

Другие вопросы по тегам