ImportError: невозможно импортировать имя NO_DEFAULT - PullRequest
1 голос
/ 18 июля 2011

Я пытаюсь запустить сценарий manage.py сайта Django, но он завершается ошибкой:

Traceback (most recent call last):
  File "manage.py", line 2, in <module>
    from django.core.management import execute_manager
  File "/scratch/tools/lib/python2.5/site-packages/django/core/management/__init__.py", line 4, in <module>
    from optparse import OptionParser, NO_DEFAULT
ImportError: cannot import name NO_DEFAULT

Это происходит независимо от того, использую ли я Python 2.5.1 или 2.6.1 (пакеты Fedora). Я могу воспроизвести ошибку при импорте в интерактивном сеансе Python.

Это не очень удивительно, учитывая, что NO_DEFAULT не указан в optparse.py __all__ и также не указан в optparse документации .

Что удивительно, так это то, что на моей рабочей станции я могу успешно выполнить from optparse import NO_DEFAULT в Python 2.5.5 и 2.6.6 (пакеты Debian).

У меня двоякий вопрос:

  • Как может быть, что я могу импортировать то, что не указано в __all__?
  • Как мне починить Джанго manage.py? Я хочу, чтобы он работал с Python 2.5, если это вообще возможно.

1 Ответ

0 голосов
/ 18 июля 2011

Как всегда в Python, __all__ является скорее руководством, чем правилом.Это происходит из-за того, что мы любим-ненавидим *-import, описанные в документах как

Если список идентификаторов заменяется звездочкой ('*'), все публичные имена, определенные в модуле, связаны в локальном пространстве имен оператора import.

Здесь возникает непосредственная техническая трудность: как интерпретатору знать, что такое публичнаяимена модуля есть?Существует соглашение, что любое имя в модуле, не начинающееся с _, является открытым;Вы можете подумать, что в первом приближении нужно просто импортировать все такие имена в пространство имен модуля.К сожалению, это становится более сложным, когда вы представляете пакеты, потому что тогда вычисление открытых имен становится большой задачей, включающей различные операции импорта, переписывания путей, чтения файлов и что у вас есть.Это не хорошая вещь.Таким образом, было принято упрощающее решение, позволяющее автору модуля точно указать, какие имена в пакете следует импортировать из * -импорта, определив __all__ в модуле.

Но если вы этого не сделаете* -import - если вы дадите интерпретатору имя переменной, которую вы хотите импортировать, - ему не нужно беспокоиться о поиске всех глобальных имен, поэтому он может игнорировать __all__ и просто искать имя впространство имен модуля.

Это означает, что __all__ может не совпадать с подмножеством locals().keys(), не начинающимся с подчеркивания.В частности, в модуле могут быть совершенно хорошие объекты, которые не экспортируются * -импортами.Вот что происходит с NO_DEFAULT.

...