cooperation of buitlin methods usingtsuper

Michele Simionato mis6 at pitt.edu
Wed Jul 2 12:55:11 EDT 2003


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 ;)

> 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__()

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? 

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

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


               Michele




More information about the Python-list mailing list