Проблема не в том, что __str__()
не переопределяется (как вы уже сказали, это так), а в том, что str(e)
(который невидимо вызывается при печати) это , а не всегда эквивалентно e.__str__()
.Более конкретно, если я правильно понял, str()
(и другие специальные методы, такие как repr()
), не будут искать str в словаре экземпляра - он будет искать его только вКлассовый словарь.По крайней мере, так обстоит дело с так называемыми классами нового стиля (которые являются единственными классами в Python 3.x IIRC).Вы можете прочитать больше об этом здесь:
http://mail.python.org/pipermail/python-bugs-list/2005-December/031438.html
Если вы хотите изменить сообщение об ошибке исключения для повторного исключения, вы можете сделать что-то вроде этого:
def reraise(exception):
"""
Re-raise an exception and override its output
"""
exType = type(exception)
newExType = type(exType.__name__ + "_Override", (exType,), { '__str__': str_override})
exception.__class__ = newExType
# Re-raise and remove ourselves from the stack trace.
raise exception, None, sys.exc_info()[-1]
Это динамически выведет новый класс исключений с переопределением str и изменит исключение на экземпляр этого класса.Теперь ваш код должен работать.