Выяснение того, что ДЕЙСТВИТЕЛЬНО пошло не так, когда вызывается `ImportError` - PullRequest
3 голосов
/ 24 февраля 2011

Взять, к примеру, Django, в manage.py:

try:
    import settings
except ImportError:
    sys.stderr.write("Error: Can't find the file 'settings.py'...")

Кажется законным, но что происходит, когда settings импортирует non_existant_lib_foo?

Ну, вы отправлены в погоню за всеми возможными вещами, которые вы могли бы сделать с PATH и т. Д.

Конечно, вы можете использовать except ImportError as e: и просто распечатать фактическое сообщение об ошибке, но что, если вы хотите отловить только конкретную ошибку и дать действительно хороший совет, как выше?

Вам осталось более или менее использовать регулярное выражение или, в лучшем случае, предположить, что «правому» модулю не удалось импортировать, а затем отобразить сообщение.

Есть ли лучший способ справиться с этим?

Ответы [ 3 ]

5 голосов
/ 24 февраля 2011

В основном проблема заключается в том, что ваше сообщение об ошибке неверно - существуют другие причины, по которым импорт может не работать, а не просто неправильные пути. ImportError просто означает «вы не можете использовать этот модуль, посмотрите на трассировку, чтобы выяснить, почему», вы просто пришли к выводу.

Если вы хотите отобразить «Не удается найти файл», то вам следует сначала поискать файл. imp.find_module делает это.

0 голосов
/ 24 февраля 2011

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

try:
    import settings
except ImportError as exc:
    sys.stderr.write("Error: failed to import settings module ({})".format(exc))

Таким образом, вы получите ясное сообщение в общем случае (например, пользователь поместил свой файл настроек в неправильное место, или где-то произошла ошибка конфигурации, так что sys.path не так), не скрывая полностьюдругие ошибки импорта, возникающие при выполнении модуля settings.

Еще лучше, если при использовании модуля ведения журнала, регистрировать полную информацию об исключении (включая трассировку) как debug() или info() logging event.

Существуют и другие варианты, такие как поиск по подстроке if 'settings' not in str(exc): raise или отделение местоположения модуля от его выполнения с помощью imp.find_module(), но простого включения исходного сообщения об ошибке достаточно, чтобыпредотвратить худшие неприятности.

0 голосов
/ 24 февраля 2011

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

Возьмите подсказку.

Не не ошибки импорта прерываний. Пример manage.py не является наилучшей практикой.

Не делай этого.

ошибки импорта должны быть очень, очень редкими.

...