Если вы посмотрите документацию по встроенным ошибкам , вы увидите, что большинство Exceptionклассов назначают свой первый аргумент как messageатрибут. Но не все из них.
Примечательно, что EnvironmentError(с подклассами IOErrorи OSError) имеет первый аргумент errno, второй из strerror. Нет message... strerrorпримерно аналогично тому, что обычно было бы message.
В более общем плане подклассы Exceptionмогут делать все, что захотят. Они могут иметь или не иметь messageатрибут. Будущие встроенные Exceptionобъекты могут не иметь messageатрибута. Любой Exceptionподкласс, импортированный из сторонних библиотек или пользовательского кода, может не иметь messageатрибута.
Я думаю, что правильный способ справиться с этим - определить конкретные Exceptionподклассы, которые вы хотите поймать, а затем поймать только те, а не все с помощью except Exception, а затем использовать любые атрибуты, которые определяет конкретный подкласс, как вы хотите.
Если вам printчто-то нужно , я думаю, что печать пойманного Exception, скорее всего, сделает то, что вы хотите, независимо от того, есть ли у него messageатрибут или нет.
Вы также можете проверить атрибут сообщения, если хотите, например, вот так, но я бы не стал предлагать это, поскольку это просто кажется беспорядочным:
try:
pass
except Exception as e:
if hasattr(e, 'message'):
print(e.message)
else:
print(e)
except Foo as bar:то же самоеexcept Foo, bar:(за исключением того, что первое новее и будет продолжать работать в 3.x), независимо от того, идет ли ошибка сmessageатрибутом или нет, является отдельным.