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

Joel Bender jjb5 at cornell.edu
Thu Apr 26 20:55:14 CEST 2007


I've come late to this thread, and misunderstood what was wrong with super(), so a thousand pardons please. But since that's never stopped me before...

Guido van Rossum wrote:

But:

class E(D): pass print E().f() This prints DDBCA which surely isn't right. Sounds like the classic bug in such attempts.

About about this?

class _super(property): def init(self): property.init(self, self.get_super, None, None) def get_super(self, klass): class wrapper: def getattr(self, fn): self.fn = fn return self def call(self, obj, *args, **kwargs): mro = iter(obj.class.mro) for cls in mro: if cls is klass: break for cls in mro: f = getattr(cls, self.fn) if f: return f(obj, *args, **kwargs) raise AttributeError, self.fn return wrapper()

class _superable(type): super = _super()

class A(object): metaclass = _superable def f(self): return "A"

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

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

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

class E(D): pass

assert E().f() == "DBCA"

Tim Delaney wrote:

What I haven't worked out yet is if you should be able to do the following:

class A(autosuper):
    def f(self):
        print 'A:', super

class B(A):
    def f(self):
        def inner():
            print 'B:', super
            super.f()
        inner()

And here's my version:

class A(object): metaclass = _superable def f(self): return "A"

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

assert B().f() == "BA"

Now, back to the original request, I came up with this:

def super(klass, obj=None): class wrapper: def init(self): self.klass = klass self.obj = obj def getattr(self, fn): self.fn = fn return self def call(self, *args, **kwargs): if not self.obj: self.obj = args[0] args = args[1:] mro = iter(self.obj.class.mro) for cls in mro: if cls is self.klass: break for cls in mro: f = getattr(cls, self.fn) if f: return f(self.obj, *args, **kwargs) raise AttributeError, self.fn return wrapper()

class A(object): def f(self): return "A"

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

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

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

class E(D): pass

assert E().f() == "DBCA"

I prefer the version in C, but B works as well. Comments? Is this ground that has already been covered?

Joel



More information about the Python-3000 mailing list