New Python features, and super()
I'm a long time Python user (since 1994) and fan, and lately I've been trying to catch up on some of the many changes the language have been going through. I must say, pretty much everything they have changed or added since the old 1.x days are awesome! As if Python wasn't a great language already, it's shaping up to be a very strong contender indeed.
If you haven't looked at Python lately, take a quick look at the following "summaries" of changes that's been made in recent years:
- What's new in python 2.0
- What's new in Python 2.1
- What's new in Python 2.2
- What's new in Python 2.3
- What's new in Python 2.4
- What's new in the next Python
- Python PEPs
Anyways, last week I was playing with the super() function, to clean up some old code which used the old style calling conventions for accessing the super class members. This new built-in function was added to Python 2.2, to better support the new multiple inheritance lookup rules (see above). The following example shows the two different styles (but read the docs above for more in depth analysis why using super() is useful):
class Foo(BaseFoo):
def __init__(self, arg1, arg2):
BaseFoo.__init__(self, arg1, arg2)
...
class Bar(BaseBar):
def __init__(self, arg1, arg2):
super(Bar, self).__init__(arg1, arg2)
...
This worked most of the time in my code, except when I tried to sub-class some old-style classes, for instance:
from HTMLParser import HTMLParser, HTMLParseError
class HTMLImageParser(HTMLParser):
def __init__(self, callback=None):
super(HTMLImageParser, self).__init__()
....
This would generate an error like:
TypeError: super() argument 1 must be type, not classobj
The simple solution was to change my sub-class to also be a sub-class of the object class, making it a new-style class:
class HTMLImageParser(HTMLParser, object):
def __init__(self, callback=None):
super(HTMLImageParser, self).__init__()
...