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

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

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

но я получаю:

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

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

Спасибо.

Ответы [ 6 ]

38 голосов
/ 29 марта 2010

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

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

5 голосов
/ 29 марта 2010

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

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

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

4 голосов
/ 10 июня 2017

Для 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
4 голосов
/ 29 марта 2010

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

>>> 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__"
2 голосов
/ 11 апреля 2017

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

%load_ext autoreload
%autoreload 2

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

См. Документы:

0 голосов
/ 29 марта 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...