cooperation of buitlin methods usingtsuper

Matthias Oberlaender matthias.oberlaender at VOID.daimlerchrysler.com
Thu Jul 3 09:21:48 CEST 2003


In <2259b0e2.0307020855.478300c2 at posting.google.com> Michele Simionato wrote:
> Matthias Oberlaender <matthias.oberlaender at REMOVE.daimlerchrysler.com> 
wrote in message news:<bduh36$rgn$1 at news.sns-felb.debis.de>...> I would like  
to adopt the cooperation paradigm in conjunction with builtin 
> > methods and operators, such as len, iter, +, * etc. 
> 
> Fine.
> 
> > But the direct approach does not work with the current implementation of 
> > super. For example, 'len(super(Y, y)' will always result in 'len() of 
> > unsized object'.
> 
> Of course, it must give an error! I think you do not understand how 
> super works. But don't worry, that's quite common ;)

Oh, wait a minute. I think this "of course" is a bit presumptuous. 

> 
> > As far as I understand, this is because builtins don't use a dynamic 
lookup 
> > chain, but go directly to the slots for the builtins. However, super 
returns 
> > an instance of class 'super'. Since all super objects share this class,  
its 
> > slots will not be filled as one might hope. 
> 
> > My workaround is this: I create a subclass of 'super' on the fly each 
time I 
> > call 'mysuper'.  Look at the definition below.  It seems to work. But 
maybe 
> > I have overlooked something. Is my understanding correct? Is 'mysuper' a 
> > good solution? Possible improvements? (e.g. caching of subclasses)
> 
> > Thanks for comments!
> 
> 
> > import new
>  
> > class X(object):
> >  def __len__(self): return 2222
> 
> > class Y(X):
> >  def __len__(self): return 1111
> 
> > def mysuper(cls, inst):
> >   return new.classobj('mysuper', (super,) + cls.__bases__, {})(cls, inst)
> 
> > y = Y()
> > try:
> >  print len(super(Y, y))
> > except Exception, msg:
> >  print msg
> 
> > try:
> >  print len(mysuper(Y, y))
> > except Exception, msg:
> >   print msg
> 
> >Output:
> 
> > len() of unsized object
> > 2222
> 
> I think you should re-read the documentation and
> google on the newsgroup for 'super'. The use case
> for super is in multiple inheritance, as in this example:
> 
> class B(object):
>     def __len__(self):
>       print 'called B.__len__'
      return 1111
>     
> class C(B):
>   def __len__(self):
>       print 'called C.__len__'
>       return super(C,self).__len__()

This is exactly the style of syntax I want to avoid! I'd rather write more 
concisely 'len(super(C,self))'.  
Why should its non-working be an intended feature? It becomes even more 
annoying  in the case of binary operators like  __add__, for example:

super(X,self).__add__(other)   vs.   super(X,self) + other

Which one would you prefer? Using ordinary super, I can't use all the 
"syntactic sugar" of infix operator syntax any more that make expressions so 
much more readable.

> > 
> class D(B):
>   def __len__(self): 
>       print 'called D.__len__'
>       return super(D,self).__len__()
> 
> class E(C,D):
>     pass
> 
> print len(E())
> 
> The output of this is
> 
> called C.__len__
> called D.__len__
> called B.__len__
> 1111
> 
> Do you see why? Feel free to ask if not. I do not understand what behavior 
> you expect from 'super'. Can you give more details on your specific use 
case? 
> 
Yes. I can see why. I'd dare to say I understand super fairly well now, 
including the diamond rule. But its benefit is not restricited to the 
multiple inheritance case. So we can leave MI and the "diamond" aside. 

What I expect from super(x.__class__, x) is an object that behaves exactly as 
if  x.__class__ where devoid of any _own_ attributes, as if it had been 
defined like this: 

class X(A,B,C,...): pass

And these expectations are almost met. But, at least in Python 2.2.1, its is 
a matter of fact that builtins/special method names are treated differently 
from ordinary class methods in conjunction with super objects. Do you agree? 
My implementation of super seems to fix this gap. Perhaps there are some 
other people who would appreciate that too. Or are there good 
logical/conceptual reasons againts it? This is what I would like to know.

> P.S. BTW, in Python 2.2+ you can replace ``new.classobj(name,bases,dic)``
> with the built-in ``type(name,bases,dic)``.

Thanks's for the tip (and your response)!

--
 ____  __  _/_/ . 
( / / ( /  / / /  

=====================================================================
Matthias Oberlaender, DaimlerChrysler AG, Research Center Ulm
RIC/AP (Machine Perception)
Wilhelm-Runge-Str. 11,  P.O. Box 2360,  89013 Ulm, Germany
Phone: +49 731 505 2354       Fax: +49 731 505 4105
Email: matthias.oberlaender at REMOVE.daimlerchrysler.com
=====================================================================





More information about the Python-list mailing list