Welcome, guest | Sign In | My Account | Store | Cart

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, 36 lines
 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()

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!

2 comments

Michele Simionato 17 years, 6 months ago  # | flag

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

Tim Delaney 16 years, 9 months ago  # | flag

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.

Created by Paul McNett on Thu, 22 Apr 2004 (PSF)
Python recipes (4591)
Paul McNett's recipes (1)

Required Modules

Other Information and Tasks