Jeśli przejrzysz dokumentację dotyczącą błędów wbudowanych , zobaczysz, że większość Exceptionklas przypisuje pierwszy argument jako messageatrybut. Nie wszyscy jednak.
Warto zauważyć, że EnvironmentError(z podklasami IOErrori OSError) ma pierwszy argument errno, drugi z strerror. Nie ma message... strerrorjest mniej więcej analogiczne do tego, co normalnie byłoby message.
Mówiąc bardziej ogólnie, podklasy Exceptionmogą robić, co chcą. Mogą mieć messageatrybut lub nie . Przyszłe wbudowane elementy Exceptionmogą nie mieć messageatrybutu. Żadna Exceptionpodklasa zaimportowana z bibliotek innych firm lub kod użytkownika może nie mieć messageatrybutu.
Myślę, że właściwym sposobem radzenia sobie z tym jest zidentyfikowanie konkretnych Exceptionpodklas, które chcesz wyłapać, a następnie wyłapanie tylko tych, a nie wszystkiego za pomocą znaku except Exception, a następnie wykorzystanie dowolnych atrybutów, które określona podklasa definiuje, jak chcesz.
Jeśli musisz printcoś, myślę, że drukowanie złapanego Exceptionsamego siebie najprawdopodobniej zrobi to, co chcesz, bez względu na to, czy ma messageatrybut, czy nie.
Możesz również sprawdzić atrybut wiadomości, jeśli chcesz, w ten sposób, ale tak naprawdę nie sugerowałbym tego, ponieważ wydaje się po prostu niechlujny:
try:
pass
except Exception as e:
if hasattr(e, 'message'):
print(e.message)
else:
print(e)
except Foo as bar:jest to to samo, coexcept Foo, bar:(z wyjątkiem tego, że pierwsza jest nowsza i będzie działać w 3.x), niezależnie od tego, czy błąd występuje zmessageatrybutem, czy nie.