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

Guido van Rossum guido at python.org
Thu Apr 26 21:06:45 CEST 2007


Writing B.super.f(self) instead of super(B, self).f() is not an improvement.

On 4/26/07, Joel Bender <jjb5 at cornell.edu> wrote:

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.getsuper, None, None) def getsuper(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


Python-3000 mailing list Python-3000 at python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/guido%40python.org

-- --Guido van Rossum (home page: http://www.python.org/~guido/)



More information about the Python-3000 mailing list