Pb with descriptor and super ...

Arnaud Delobelle arnodel at googlemail.com
Fri Mar 9 12:56:14 EST 2007


On Mar 9, 11:22 am, Erwan Adam <erwan.a... at cea.fr> wrote:
[snip]
>
> [adam at is111902 /home/adam/Work/Python]> python super_from_guido.py
> Using built-in super
> Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c>
> and typ is <class '__main__.B'>
> Using python Super
> Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c>
> and typ is None
> Using python MySuper
> Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c>
> and typ is <class '__main__.A'>

It seems to me that it is the built-in super which has the correct
behaviour.  When you write obj.attr, python calls  attr.__get__(obj,
type(obj)) and not attr.__get__(obj) which sets the second arg to
None. You can check this by creating a barebone descriptor that simply
prints its arguments:

class D(object):
    def __get__(self, obj, objtype):
        print obj, objtype

class A(object):
    d=D()

A().d
<__main__.A object at 0x133c5f0> <class '__main__.A'> # objtype is not
None!

Therefore in your case when you do super(B, b).attr then
A.__dict__['attr'].__get__(b, type(b)) is called. You can try this, it
should give the same output as builtin super.

> the Super gives None for typ ... which is quite surprising !
> In MySuper, I just change
>
>                      x = x.__get__(self.__obj__)
>
> by
>
>                      x = x.__get__(self.__obj__, cls)
> at the -3 :) line of the class ... and it gives the result I expected
> at the beginning : obj is b and typ is A !!!!

Neither of these are right I think. If my explanation above is right
the correct line should be:
                    x = x.__get__(self.__obj__, type(self.__obj__))

HTH

--
Arnaud




More information about the Python-list mailing list