Simple super

written by Martin Häcker on

Python is a wonderfull language - except when it's not.

For example calling a super-method is really, really hard. Here's an example:

class Super(object):
    def method(self):
        pass

class Sub(Super):
    def method(self):
        super(Sub, self).method()

This is bad because of several reasons:

If your class names become longer this becomes more and more unreadable, consider this Acceptance-Test

class CanEnterUsernameAndPasswordOnLoginForm(TestCase):
    def setUp(self):
        super(CanEnterUsernameAndPasswordOnLoginForm, self).setUp()
        # more

You need to repeat the class name in each method that calls super. This is especially bad if you rename your class as you need to repeat the name in so many places - also there might be situations where having the wrong name doesn't bomb but just calls the wrong code. Also if you move methods up and down the class-inheritance-chain this becomes more and more annoying.

Well, so I looked at what you can do with some meta-programming - and lo and behold there's a lot you can do.

Here's an example what I ended up with:

class Super(object):
    super = SuperProxy()
    def method(self):
        pass

class Sub(Super):
    def method(self):
        self.super()

Yeah! Now that's simpler. to call super you can use several syntaxes:

  • self.super() just calls the super method of the same name and hands it all arguments that the current method got
  • self.super('foo') this way you can hand specific methods to the super-class and prevent the automatic gathering of arguments. If you prefer explicit - this is it.
  • self.super.some_method() self.super is exactly the same as what the super-method returns (so it's the same as super(ThisClass, self)) so you can use it to call any method on the superclass and hand it any arguments you want.

Well, so I consider this a boon for any bigger python project as it considerably eases the pain of working with class-hierarchies, and best of all you can import it into your project one superclass at a time.

Oh, and please tell me if you use it and like it. :-)

So [browser:/open-source/python-simple-super/trunk/simple_super.py here's the code!]