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

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.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
>
> _______________________________________________
> 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