2012-05-01 3 views
9
$ python 
>>> import myapp 
>>> reload(myapp) 
<module 'myapp' from 'myapp.pyc'> 
>>> 

Ctrl + DReload интерпретатор Python

$ python 
>>> from myapp import * 
>>> reload(myapp) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'myapp' is not defined 

Почему это ведет себя по-другому? Как я могу перезагрузить при использовании from myapp import *?

+0

Причина, по которой я использую * reload() *, заключается в том, что я меняю исходный код модуля и проверяю его, и причина, по которой я использую * из myapp import *, заключается в том, что он меня печатает. – xralf

+1

'reload' должен использоваться с * лотом *. Это ведет себя неожиданно во многих отношениях, худшим из которых является то, что классы существуют во многих версиях внутри виртуальной машины, в зависимости от того, существуют ли у вас старые экземпляры перезагруженных классов. По этой причине из Python 3 был удален «reload». Часто намного проще настроить небольшой скрипт, устанавливающий все необходимые вам модули, а затем переходить в оболочку с использованием кода импорта; code.interact (местные жители =()) '.Интерпретатор Python запускается очень быстро, поэтому обычно это происходит быстрее, чем поиск «перезагрузки» в истории чтения. –

+0

@NiklasB. Спасибо за совет, но я не могу представить это без какого-либо примера. Если это возможно, и у вас есть время, чтобы написать об этом больше, отправьте пример ответа. Или я могу создать новый вопрос, основанный на вашем комментарии, если вы не против. – xralf

ответ

17

От http://docs.python.org/library/functions.html#reload:

Если объектов импортирует модуль из другого модуля, используя из ... импорта ..., вызывая перезагрузку() для другого модуля не переопределить объектов, импортированных из него - один из способов заключается в том, чтобы повторно выполнить оператор , а другой - использовать импортные и квалифицированные имена (модуль имя).

Таким образом, вы должны сделать что-то вроде:

from myapp import * 
.... 
import myapp 
reload(myapp) 
from myapp import * 
2

Как можно перезагрузить при использовании from myapp import *?

Вы не можете. Это одна из причин, почему использование from X import * - плохая идея.

+2

Неплохая идея при отладке. Это позволяет печатать на машинке. – xralf

3

from myapp import * С, у вас нет ссылки на ваш модуль в имени переменной, так что вы не можете использовать имя переменной для обозначения к модулю.

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

import myapp 
reload(myapp) 

Вы также можете получить ссылку непосредственно из sys.modules.

import sys 
reload(sys.modules["myapp]") 
+0

Импорт и перезагрузка модуля фактически не перевязывает имена, связанные с 'from foo import *'. Это может или многие из них не делают перезагрузку бесполезной. – geoffspear

+0

Причина, по которой я использую * reload() *, заключается в том, что я меняю исходный код модуля и проверяю его, и причина, по которой я использую * из myapp import *, заключается в том, что он меня печатает. – xralf

1

Для уточнения комментария Wooble, используя «от Foo импорта *» приносит все из обув в текущее пространство имен. Это может привести к конфликтам имен (где вы непреднамеренно присваиваете новое значение имени, которое уже используется), а также затрудняет определение того, откуда что-то произошло. Хотя несколько библиотек часто используются таким образом, обычно это вызывает больше проблем, чем того стоит.

Кроме того, поскольку он был перенесен в текущее пространство имен, его нельзя просто перезагрузить. Обычно лучше хранить его в отдельном пространстве имен (возможно, с более коротким псевдонимом удобства, например, просто m). Это позволяет вам перезагружать (что полезно для тестирования, но редко хорошая идея вне тестирования) и помогает использовать его пространство имен чистым.

Смежные вопросы