hvishwanath
hvishwanath

Reputation: 11

How are the arguments being passed up to super in the below code?

Python 2.7.3 (default, Sep 26 2012, 21:53:58) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> c = Exception("asdf")
>>> c.message
'asdf'
>>> class E(Exception):
...     def __init__(self, ec, *args, **kwargs):
...             self.errorcode = ec
...             super(Exception, self).__init__(*args, **kwargs)
... 
>>> e = E(-1, "asdfasdf")
>>> e
E('asdfasdf',)
>>> e.message
'asdfasdf'
>>> e.errorcode
-1
>>> class DE(E):
...     def __init__(self, *a, **kw):
...             self.errorcode = -1111
...             super(E, self).__init__(*a, **kw)
... 
>>> d = DE("asdf")
>>> d.errorcode
-1111
>>> d.message
'asdf'
>>> class DE(E):
...     def __init__(self, *a, **kw):
...             self.errorcode = -1111
...             super(E, self).__init__(self.errorcode, *a, **kw)
... 
>>> d = DE("asdf")
>>> d.message
''
>>> d.errorcode
-1111
>>>

Let me explain the above code a little bit. e = Exception("My message"), will result in e.message="My message".

Now I create a custom Exception class E deriving from Exception class. It has an additional positional argument ec. When I create E(-1,"some message"), E.message="some message" works as expected.

Now I create DE(E). Now in the call to super, I only do super(E, self).__init__(*args, **kwargs) - note that I am not passing the error code, though E's init expects an error code as the first argument. DE("some message") in this case results in DE.message="some message".

Next, the super call is modified to be super(E, self).__init__(self.errorcode, *args, **kwargs) -> this is the expected signature in E. When this is done, DE("some message") results in DE.message = ''.

I am not too sure why this behavior is happening. Will be grateful if somebody can explain this.

Upvotes: 1

Views: 88

Answers (2)

Wubao Li
Wubao Li

Reputation: 1748

  1. as @user2357112 said, you're using super function wrong. super(E) is proxy to E's super, not E itself.

  2. About your code, this is a special case:

    Exception is a built-in type, it's super class is BaseException, so when you call super(Exception),it is proxy to BaseException.

    in the derived class of Exception, when you call super(E) is proxy to Exception type.

    in BaseException's init method, if only one parameter pass in, the parameter assign to message property, if parameter count not equal to 1, it will assign nothing to message property. And Exception's init just call BaseException's init, so the same result.

    errorcode is always a property of current object, so it's always seems right.

    when you call

super(E, self).init(self.errorcode, *a, **kw)

there are two parameters, (-1111, 'asdf'), so the exception message is ''

try this:

e = Exception(-1111,'asdf')

e.args

e.message

and this:

e = Exception(-1111)

e.args

e.message

Upvotes: 0

user2357112
user2357112

Reputation: 280953

You're using super wrong. The first argument is supposed to be the class you're defining, not the superclass. super(E, self) skips past E to Exception, so neither version of DE calls E's constructor at all.

Upvotes: 1

Related Questions