Multiple inheritance
Besides the basic OOP stuff that I covered in my last post there are some things that you can do in IronPython which is not possible in languages like C# and java.
One nice thing that I have heard people moan about not having in other languages is multiple inheritance. Working with it is very straight forward in Python as the following sample illustrates:
class MyFirstClass:
def MethodOne(self, arg):
print "1 " + arg
class MySecondClass:
def MethodOne(self, arg):
print "1 Overwritten " + arg
def MethodTwo(self, arg):
print "2 " + arg
class MyThirdClass(MySecondClass, MyFirstClass):
def MethodThree(self, arg):
print "3 " + arg
class MyFourthClass(MyFirstClass, MySecondClass):
def MethodFour(self, arg):
print "4 " + arg
Multiple inheritance is obtained simply by listing the classes that are to be inherited, where the order dictates the precedence of the members. This means that if the classes inherited have methods with the same signature, the first class takes precedence.
The following code can be used to test the above classes, and it also illustrates that a variable name can be reused for different types, which is a very basic feature of dynamic languages. Basic as it may be it is also one of the things that can make code really messy!
t = MyThirdClass()
t.MethodOne("MethodOne")
t.MethodTwo("MethodTwo")
t.MethodThree("MethodThree")
t = MyFourthClass()
t.MethodOne("MethodOne")
t.MethodFour("MethodThree")
Monkey patching
I wrote in my last post that it is possible to modify objects and add methods to the instance itself. Besides that it is also possible to add methods to the class in the same way. Adding or overriding methods in this way is sometimes referred to as monkey patching. As with multiple inheritance it can get really messy, but used wisely it can also make code really simple and elegang. An obvious place to use this is for mocking when writing unittests. A simple way to illustrate the technique is to first create a class and two methods:
class MyFirstClass:
def MethodOne(self, arg):
print "1 " + arg
def MethodTwo():
return "Monkey patched to instance 2"
def MethodThree(self):
return "Monkey patched to class 3"
Now the methods can be monkey patched onto the instance and class as the following code illustrates.
t = MyFirstClass()
t.MethodTwo = MethodTwo
MyFirstClass.MethodThree = MethodThree
t.MethodOne("MethodOne")
print t.MethodTwo()
print t.MethodThree()
As the observant reader will notice it is required that MethodThree which is added to the class takes the self argument, where MethodTwo which is added to the instance does not.