4

I've never fully understood exception handling in Python (or any language to be honest). I was experimenting with custom exceptions, and found the following behaviour.

class MyError(Exception):
    def __init__(self, anything):
        pass

me = MyError("iiiiii")
print(me)

Output:

iiiiii

I assume that print() calls Exception.__str__().

How does the base class Exception know to print iiiiii? The string "iiiiii" was passed to the constructor of MyError via the argument anything, but anything isn't stored anywhere in MyError at all!

Furthermore, the constructor of MyError does not call its superclass's (Exception's) constructor. So, how did print(me) print iiiiii?

2
  • 1
    What version of Python? This can't be reproduced in Python 2.7. Commented Jul 21, 2016 at 9:22
  • Sorry forgot to mention, Python 3.5.1. Commented Jul 21, 2016 at 9:26

1 Answer 1

2

In Python 3, the BaseException class has a __new__ method that stores the arguments in self.args:

>>> me.args
('iiiiii',)

You didn't override the __new__ method, only __init__. You'd need to override both to completely prevent from self.args to be set, as both implementations happily set that attribute:

>>> class MyError(Exception):
...     def __new__(cls, *args, **kw):
...         return super().__new__(cls)  # ignoring args and kwargs!
...     def __init__(self, *args, **kw):
...         super().__init__()           # again ignoring args and kwargs
...
>>> me = MyError("iiiiii")
>>> me
MyError()
>>> print(me)

>>> me.args
()

In Python 2, exceptions do not implement __new__ and your sample would not print anything. See issue #1692335 as to why the __new__ method was added; basically to avoid issues like yours where the __init__ method does not also call super().__init__().

Note that __init__ is not a constructor; the instance is already constructed by that time, by __new__. __init__ is merely the initialiser.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.