[Python-3000] Fixing super anyone? (reflux) (original) (raw)
Joel Bender jjb5 at cornell.edu
Thu Apr 26 20:55:14 CEST 2007
- Previous message: [Python-3000] [Python-Dev] Pre-pre PEP for 'super' keyword
- Next message: [Python-3000] Fixing super anyone? (reflux)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Previous message: [Python-3000] [Python-Dev] Pre-pre PEP for 'super' keyword
- Next message: [Python-3000] Fixing super anyone? (reflux)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]