Bob Fang
Bob Fang

Reputation: 7411

Which to use: self or super?

I am wrapping up a python class deque to queue to make my code more readable:

from collections import deque

class Queue(deque):
    def enqueue(self,a):
        super(Queue, self).append(a)

    def dequeue(self,a):
        super(Queue, self).popleft(a)

My question is which one I should use here, self.append() or super(Queue, self).append(), Why?

Upvotes: 2

Views: 204

Answers (4)

Ellioh
Ellioh

Reputation: 5330

super() is used to call a base class method that is redefined in the derived class. If your class were defining append() and popleft() methods extending their behavior, it would be reasonable to use super() inside append() and popleft(). However, your example redefines nothing from deque, so there is no need for super().

The following example shows when super() is used:

class Queue(deque):
    def append(self, a):
        # Now you explicitly call a method from base class
        # Otherwise you will make a recursive call
        super(Queue, self).append(a)
        print "Append!!!"

However, in case of multiple inheritance what super() does is more complicated than just allowing to call a method from base class. Detailed understanding requires understanding MRO (method resolution order). As a result, even in the example above it is usually better to write:

class Queue(deque):
    def append(self, a):
        # Now you explicitly call a method from base class
        # Otherwise you will make a recursive call
        deque.append(self, a)
        print "Append!!!"

Upvotes: 2

Amelia
Amelia

Reputation: 2970

Who told you it was a good idea to even think of using super instead of self? You want to affect a single instance of the Queue, not append a to the module scope (never mind the fact that super.append throws AttributeError)

from collections import deque

class Queue(deque):
    def enqueue(self, a):
        self.append(a)

    def dequeue(self, a):
        self.popleft(a)

Upvotes: 0

Emil Ivanov
Emil Ivanov

Reputation: 37633

Go for self (putting aside that your use of super is incorrect as Borealid stated).

However, I believe that in this case it's better to not extend deque, but rather wrap it.

from collections import deque

class Queue(object):
    def __init__(self):
        self.q = deque

    def enqueue(self, a):
        return self.q.append(a)

    def dequeue(self, a):
        return self.q.popleft(a)

Also, note the returns - in your code they are missing and you cannot get the dequeued value.

Upvotes: 1

Borealid
Borealid

Reputation: 98529

Given these two choices, you should use self.append, because your code using super is not valid Python.

The correct alternate version would be super(Queue, self).append.

Upvotes: 1

Related Questions