Проверка имени модуля внутри 'except ImportError'
try:
import MySQLdb
# some action
except ImportError as err:
# fallback code
PyCharm дает предупреждение о проверке кода:
'MySQLdb' в блоке try с 'except ImportError' также должен быть определен за исключением блока
Эта проверка обнаруживает имена, которые должны быть разрешены, но нет. Из-за динамической отправки и утиной печати это возможно в ограниченном, но полезном числе случаев. Элементы верхнего уровня и уровня класса поддерживаются лучше, чем элементы экземпляра.
Хорошо, я думал, что предупреждение разумно, потому что fallback code
предполагает, что 'MySQLdb' не установлен, в то время как это может быть некоторая другая ошибка, которая только что подняла ImportError. Поэтому я использовал что-то вроде:
try:
import MySQLdb
# some action
except ImportError as err:
if "MySQLdb" in repr(err):
# fallback code
else:
raise
Предупреждение PyCharm все еще существует, но это может быть просто проблема PyCharm (google показывает проблемы с такими проверками)
Вопросы:
-
Действительно ли стоит проверять имя, когда вы "за исключением ImportError"? Даже в простых случаях (нет some action
после import MySQLdb
)?
-
Если это стоит проверить, Правильно ли это приведенный выше пример? Если нет - какой правильный путь?
P.S. MySQLdb - это всего лишь пример модуля, который может отсутствовать в системе.
Ответы
Ответ 1
Я думаю, что вы неправильно поняли предупреждение, если вы не определяете переменную с именем MySQLdb
в блоке исключения, а затем, когда вы пытаетесь использовать модуль, вы получите NameError
:
try:
import foo
except ImportError:
pass
foo.say_foo() #foo may or may not be defined at this point!
Если модуль используется только в предложении try:
, это не проблема. Но для более общего случая проверитель ожидает, что вы определите переменную в блоке except:
try:
import foo
except ImportError:
foo = None #now foo always exists
if foo: #if the module is present
foo.say_foo()
else:
print("foo") #backup use
Ответ 2
В Python 3.3+ ImportError
имеет атрибут name
, который сообщает имя модуля, импорт которого не удался. Тогда, конечно, MySQLdb намекнул бы, что вы застряли с Python 2.