[Python-3000] Fixing super anyone? (original) (raw)

Steven Bethard steven.bethard at gmail.com
Wed Apr 25 07:26:37 CEST 2007


On 4/24/07, Steven Bethard <steven.bethard at gmail.com> wrote:

On 4/24/07, Calvin Spealman <ironfroggy at gmail.com> wrote: > I must have miscopied then because it worked perfectly here. Yes, I > meant to have the superdesc defined inside the metaclass init, > but thought I could pull it out to make it cleaner. I forgot it > actually had to be there! Here is the metaclass that works. > > class autosuper(type): > def init(cls, name, bases, clsdict): > class superdesc(object): > def get(self, obj, objcls): > return super(cls, obj) > cls.super = superdesc()

I still get the same error.

I played around with this for a while. Below is some code that does work. The trick is to redefine super() so that when you're calling get to bind a method to an instance, you bind it to the Super() instance, not the original object instance.

class Super(object): def init(self, type, obj=None): if isinstance(obj, Super): obj = obj.obj self.type = type self.obj = obj def get(self, obj, cls=None): if obj is None: raise Exception('only supports instances') else: return Super(self.type, obj) def getattr(self, attr): mro = iter(self.obj.class.mro) for cls in mro: if cls is self.type: break for cls in mro: if attr in cls.dict: x = cls.dict[attr] if hasattr(x, 'get'): x = x.get(self, cls) return x raise AttributeError, attr

class autosuper(type): def init(cls, name, bases, clsdict): cls.super = Super(cls)

class A: metaclass = autosuper def f(self): return 'A'

class B(A): def f(self): return 'B' + self.super.f()

class C(A): def f(self): return 'C' + self.super.f()

class D(B, C): def f(self): return 'D' + self.super.f()

assert D().f() == 'DBCA'

See ma, no bytecode hacks! ;-)

STeVe

I'm not in-sane. Indeed, I am so far out of sane that you appear a tiny blip on the distant coast of sanity. --- Bucky Katt, Get Fuzzy



More information about the Python-3000 mailing list