0

On a course I found the following piece of code:

class Ex(Exception):
    def __init__(self, msg):
        Exception.__init__(self, msg + msg)
        self.args = (msg,) 
try:
    raise Ex('ex')
except Ex as e:
    print(e)
except Exception as e:
    print(e)

Reading that, I thought that printing e would show exex, but it's only ex.

Shouldn't the msg + msg change it to exex?

6
  • @Chris because line 3 is concatenating msg twice. Commented Dec 14, 2020 at 3:07
  • 1
    You are manually setting .args to self.args = (msg,) If you remove that line, it prints exex Commented Dec 14, 2020 at 3:08
  • Seems like super().__init__(msg + msg) without messing with .args is better pattern. Commented Dec 14, 2020 at 3:10
  • @juanpa.arrivillaga yeah that was it. str is set by args[0] (which I didn't know) and I hadn't fully realized that the next line is setting args. Commented Dec 14, 2020 at 3:21
  • @MarkMeyer it's just an example made to confuse the student. Which clearly worked on me. Commented Dec 14, 2020 at 3:22

1 Answer 1

2

BaseException.__str__ is defined here

static PyObject *
BaseException_str(PyBaseExceptionObject *self)
{
    switch (PyTuple_GET_SIZE(self->args)) {
    case 0:
        return PyUnicode_FromString("");
    case 1:
        return PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
    default:
        return PyObject_Str(self->args);
    }
}

roughly translated into pseudocode:

def __str__(self) -> str:
    if len(self.args) == 0:
        return ''
    elif len(self.args) == 1:
        return str(self.args[0])
    else:
        return str(self.args)

so in this case, even though you initialize Exception.__init__ with a doubling of msg, you immediately clobber self.args with the original value

if you print(self.args) before you assign it, you'll see your doubled message

if you remove your self.args assignment you'll get the value you expect

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.