Gordon Wrigley Gordon Wrigley - 1 month ago 12
Python Question

What is the correct way to extend a parent class method in modern Python

I frequently do this sort of thing:

class Person(object):
def greet(self):
print "Hello"

class Waiter(Person):
def greet(self):
print "Would you like fries with that?"

The line Person.greet(self) doesn't seem right. If I ever change what class Waiter inherits from I'm going to have to track down every one of these and replace them all.

What is the correct way to do this is modern Python? Both 2.x and 3.x, I understand there were changes in this area in 3.

If it matters any I generally stick to single inheritance, but if extra stuff is required to accommodate multiple inheritance correctly it would be good to know about that.

Answer Source

You use super:

Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.

In other words, a call to super returns a fake object which delegates attribute lookups to classes above you in the inheritance chain. Points to note:

  • This does not work with old-style classes -- so if you are using Python 2.x, you need to ensure that the top class in your hierarchy inherits from object.
  • You need to pass your own class and instance to super in Python 2.x. This requirement was waived in 3.x.
  • This will handle all multiple inheritance correctly. (When you have a multiple inheritance tree in Python, a method resolution order is generated and the lookups go through parent classes in this order.)

Take care: there are many places to get confused about multiple inheritance in Python. You might want to read super() Considered Harmful. If you are sure that you are going to stick to a single inheritance tree, and that you are not going to change the names of classes in said tree, you can hardcode the class names as you do above and everything will work fine.