Raymond Hettinger wrote: > Any trick in the book (metaclasses, descriptors, etc) is fair game.
So you are asking for a serious hack, right? As soon as I saw your challenge I thought "That's difficult. Very difficult. No way I can solve that with a simple descriptor/decorator. I need more POWER. Time to look at the byteplay module". The byteplay module by Noam Raphael (http://byteplay.googlecode.com/ svn/trunk/byteplay.py) seems to exist just to make possible spectacular hacks. So I took your challenge as an opportunity to explore a bit its secrets. In doing so, I have also decided to break the rules and not to solve your problem, but a different one, which is the one I am more interested in ;) Basically, I am happy with the double underscores, but I am unhappy with the fact that a method does not know the class where it is defined, so that you have to repeat the name of the class in ``super``. With some bytecode + metaclass hackery it is possible to make the methods smart enough to recognize the class where they are defined, so your example could be solved as follows: from currentclass import CurrentClassEnabled class A(CurrentClassEnabled): def m(self): print 'A.m' def am(self): CurrentClass.m(self) # the same as A.m(self) class B(A): def m(self): print 'B.m' def bm(self): CurrentClass.m(self) # the same as B.m(self) def superm(self): super(CurrentClass, self).m() # the same as super(B, self).m() m = B() m.am() # prints 'A.m' m.bm() # prints 'B.m' m.superm() # prints 'A.m' As you see, as a byproduct, double underscores are not needed anymore, since methods are called directly from the CurrentClass. The approach also works for ordinary attributes which are not methods. The code to enable recognition of CurrentClass is short enough to be includede here, but I will qualify it as a five star-level hackery: $ cat currentclass.py # requires byteplay by Noam Raphael # see http://byteplay.googlecode.com/svn/trunk/byteplay.py from types import FunctionType from byteplay import Code, LOAD_GLOBAL, STORE_FAST, LOAD_FAST def addlocalvar(f, locname, globname): if locname not in f.func_code.co_names: return f # do nothing c = Code.from_code(f.func_code) c.code[1:1] = [(LOAD_GLOBAL, globname), (STORE_FAST, locname)] for i, (opcode, value) in enumerate(c.code[2:]): if opcode == LOAD_GLOBAL and value == locname: c.code[i+2] = (LOAD_FAST, locname) f.func_code = c.to_code() return f class _CurrentClassEnabled(type): def __new__(mcl, name, bases, dic): for n, v in dic.iteritems(): if isinstance(v, FunctionType): dic[n] = addlocalvar(v, 'CurrentClass', name) return super(_CurrentClassEnabled, mcl).__new__(mcl, name, bases, dic) class CurrentClassEnabled: __metaclass__ = _CurrentClassEnabled Enjoy! Michele Simionato -- http://mail.python.org/mailman/listinfo/python-list