Skip to content
Old-style Python class system and parent methods

Old-style Python class system and parent methods

June 9, 2008

I rather like Python’s explicit object reference requirement, whereby method definitions for a class instance have to use self as the first parameter (I should write some classes that use this instead of self some time, just to annoy myself).

But I was tripped up debugging a problem that centred on a simple class I had that needed to do a bit of housekeeping for byte streams:

from StringIO import StringIO

class MyString(StringIO):
    def __init__(self, *args, **kwargs):
        self._customized = True # Or similar housekeeping
        super(MyString, self).__init__(*args, **kwargs)

Creating an object from this class raises a TypeError:

>>> s = MyString()
Traceback (most recent call last):
  File "", line 1, in
  File "", line 4, in __init__
TypeError: super() argument 1 must be type, not classobj

Wuh? I always used super like that before, and it always worked. But my mistake here was I was sub-classing an old-style class, and super only works with new-style classes.

The correct way of calling the parent method for old-style classes:

class MyString(StringIO):
    def __init__(self, *args, **kwargs):
        self._customized = True # Or similar housekeeping
        StringIO.__init__(self, *args, **kwargs)

That works! But the distinction between the two class models is so inelegant, so clunky. It is a nasty bit of Python’s historic implementation that one needs to keep in mind, and it is knowledge that makes me no cleverer (although it does mean I’m less stupid than I was).

Of course Python 3000 removes this distinction…

Last updated on