ActiveState Code

Recipe 279604: DoDefaultMixin


Simple recipe for making it easier to call superclass method code. Instead of 'super(cls,self).methodName()' you may just use 'cls.doDefault()' for code that is easier on the eyes.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import sys


class DoDefaultMixin(object):
	''' An alternative way to call superclass method code.

	Mix this class in to your classes, and you can now use the following
	form to call superclass methods:

		retval = cls.doDefault([args])

	instead of the usual:

		retval = super(cls, self).methodName([args])
	'''
	
	def doDefault(cls, *args, **kwargs):
		frame = sys._getframe(1)
		self = frame.f_locals['self']
		methodName = frame.f_code.co_name
		return eval('super(cls, self).%s(*args, **kwargs)' % methodName)
	doDefault = classmethod(doDefault)

	
if __name__ == '__main__':
	class TestBase(list, DoDefaultMixin):
		def MyMethod(self):
			print "TestBase.MyMethod called."
			
	class MyTest(TestBase):
		def MyMethod(self):
			print "MyTest.MyMethod called."
			MyTest.doDefault()
			
	t = MyTest()
	t.MyMethod()

Discussion

Python's new-style classes are a huge step forward, and it is now much easier to call superclass method code, and we no longer need to think about issues such as Method Resolution Order, which is handled sanely now.

The new builtin method super() returns a reference to the superclass object, allowing methods to call superclass methods using the 'super(cls,self).methodname()' idiom, which is convenient but still too convoluted for my tastes. It requires typing two things (self and methodName) redundantly.

DoDefaultMixin() makes the calling of superclass method code easier to read, easier to type, and doesn't take away any functionality. Well, I'm only a low-intermediate Pythonista currently so part of the reason for submitting this recipe is to solicit comments and to see if there are holes in my approach that I haven't considered. Also, if anyone can offer suggestions on how to get rid of the eval() that would be cool too! Enjoy!

Comments

  1. 1. At 8:27 p.m. on 25 may 2004, Michele Simionato said:

    I have an alternative way of doing that. You may be interested in this recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/284528

  2. 2. At 1:52 p.m. on 28 feb 2005, Tim Delaney said:

    And another method ... http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195

    Syntax is:

    self.super(*p, **kw)
    self.super.attribute
    

    e.g.

    def __init__(self):
        self.super()
        print self.super.__init__
    

    There's a version with higher performance, etc at the web site linked from that recipe.

Sign in to comment