473,462 Members | 1,350 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Pb with descriptor and super ...

Hi all,

I have a problem with the use of descriptors
and super. The file is :

# ---------------

class Desc(object):
def __init__(self, class_name):
self.class_name = class_name
return
def __get__(self, obj, typ):
print "Desc.__get__ : class_name is %s, obj is %s and typ is
%s"%(self.class_name, obj, typ)
return
pass

class A(object):
attr = Desc("A")
pass

class B(A):
attr = Desc("B")
pass

b = B()

print "-------"
print "Getting b.attr ..."
print "I hope that : class_name is B, obj is b and typ is B"
b.attr
print "-------"
print "Getting super(B, b).attr ..."
print "I hope that : class_name is A, obj is b and typ is A but it is
not the case !"
super(B, b).attr
print "-------"

# -----------

and the result is :

-------
Getting b.attr ...
I hope that : class_name is B, obj is b and typ is B
Desc.__get__ : class_name is B, obj is <__main__.B object at 0xb7b1f8ec>
and typ is <class '__main__.B'>
-------
Getting super(B, b).attr ...
I hope that : class_name is A, obj is b and typ is A but it is not the
case !
Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7b1f8ec>
and typ is <class '__main__.B'>
-------

I expected that when getting super(B, b).attr, typ is A, but it is not
the case ...

python used :

[adam@is111902 /home/adam/Work/Python]python
Python 2.4.3 (#2, Sep 18 2006, 21:07:35)
[GCC 4.1.1 20060724 (prerelease) (4.1.1-3mdk)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

Best regards,
E.A.
Mar 9 '07 #1
5 1426
En Fri, 09 Mar 2007 06:25:08 -0300, Erwan Adam <er********@cea.fr>
escribió:
I have a problem with the use of descriptors
and super. The file is :
Descriptors for "super" behave a bit different than for classes. See
http://www.python.org/2.2/descrintro.html#cooperation

--
Gabriel Genellina

Mar 9 '07 #2
Erwan Adam a écrit :
Hi all,

I have a problem with the use of descriptors
and super. The file is :

# ---------------

class Desc(object):
def __init__(self, class_name):
self.class_name = class_name
return
def __get__(self, obj, typ):
print "Desc.__get__ : class_name is %s, obj is %s and typ is
%s"%(self.class_name, obj, typ)
return
pass

class A(object):
attr = Desc("A")
pass

class B(A):
attr = Desc("B")
pass

b = B()

print "-------"
print "Getting b.attr ..."
print "I hope that : class_name is B, obj is b and typ is B"
b.attr
print "-------"
print "Getting super(B, b).attr ..."
print "I hope that : class_name is A, obj is b and typ is A but it is
not the case !"
super(B, b).attr
print "-------"

# -----------

and the result is :

-------
Getting b.attr ...
I hope that : class_name is B, obj is b and typ is B
Desc.__get__ : class_name is B, obj is <__main__.B object at 0xb7b1f8ec>
and typ is <class '__main__.B'>
-------
Getting super(B, b).attr ...
I hope that : class_name is A, obj is b and typ is A but it is not the
case !
Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7b1f8ec>
and typ is <class '__main__.B'>
-------

I expected that when getting super(B, b).attr, typ is A, but it is not
the case ...
Moreover, on the page :

http://users.rcn.com/python/download/Descriptor.htm

the author writes :

"The call super(B, obj).m() searches obj.__class__.__mro__ for the base
class A immediately following B and then returns
A.__dict__['m'].__get__(obj, A)."

which it seems not the case ...

Is it a bug or a mis-understood ?

Regards,

E.A.

>
python used :

[adam@is111902 /home/adam/Work/Python]python
Python 2.4.3 (#2, Sep 18 2006, 21:07:35)
[GCC 4.1.1 20060724 (prerelease) (4.1.1-3mdk)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>


Best regards,
E.A.
Mar 9 '07 #3
Gabriel Genellina a écrit :
En Fri, 09 Mar 2007 06:25:08 -0300, Erwan Adam <er********@cea.fr>
escribió:
>I have a problem with the use of descriptors
and super. The file is :

Descriptors for "super" behave a bit different than for classes. See
http://www.python.org/2.2/descrintro.html#cooperation

--Gabriel Genellina
Hi Gabriel,

Thanks for your answer ... I followed the link
and tried to use the "fully functional implementation of
the super() built-in class in pure Python" given
on this page and the result is quite surprising :

# -------------

class Super(object):
def __init__(self, type, obj=None):
self.__type__ = type
self.__obj__ = obj
def __get__(self, obj, type=None):
if self.__obj__ is None and obj is not None:
return Super(self.__type__, obj)
else:
return self
def __getattr__(self, attr):
if isinstance(self.__obj__, self.__type__):
starttype = self.__obj__.__class__
else:
starttype = self.__obj__
mro = iter(starttype.__mro__)
for cls in mro:
if cls is self.__type__:
break
# Note: mro is an iterator, so the second loop
# picks up where the first one left off!
for cls in mro:
if attr in cls.__dict__:
x = cls.__dict__[attr]
if hasattr(x, "__get__"):
x = x.__get__(self.__obj__)
return x
raise AttributeError, attr

class Desc(object):
def __init__(self, class_name):
self.class_name = class_name
return
def __get__(self, obj, typ=None):
print "Desc.__get__ : class_name is %s, obj is %s and typ is
%s"%(self.class_name, obj, typ)
return
pass

class A(object):
attr = Desc("A")
pass

class B(A):
attr = Desc("B")
pass

b = B()

print "Using built-in super"
attr = super(B, b).attr
print "Using python Super"
attr = Super(B, b).attr

class MySuper(object):
def __init__(self, type, obj=None):
self.__type__ = type
self.__obj__ = obj
def __get__(self, obj, type=None):
if self.__obj__ is None and obj is not None:
return Super(self.__type__, obj)
else:
return self
def __getattr__(self, attr):
if isinstance(self.__obj__, self.__type__):
starttype = self.__obj__.__class__
else:
starttype = self.__obj__
mro = iter(starttype.__mro__)
for cls in mro:
if cls is self.__type__:
break
# Note: mro is an iterator, so the second loop
# picks up where the first one left off!
for cls in mro:
if attr in cls.__dict__:
x = cls.__dict__[attr]
if hasattr(x, "__get__"):
x = x.__get__(self.__obj__, cls)
return x
raise AttributeError, attr

print "Using python MySuper"
attr = MySuper(B, b).attr
# ------------------------------

it gives :

[adam@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'>

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 !!!!
Best regards,

E.A.
Mar 9 '07 #4
En Fri, 09 Mar 2007 08:22:46 -0300, Erwan Adam <er********@cea.fr>
escribió:
Thanks for your answer ... I followed the link
and tried to use the "fully functional implementation of
the super() built-in class in pure Python" given
on this page and the result is quite surprising :
It appears that there is some disagreement on how the super object should
behave.
If you want to know what it actually *does* now (not what it *should* do)
you can look at typeobject.c, but it's a bit hard to read, and I don't
understand it in full...
Maybe looking at the test suite is easier, in test_descr.py

--
Gabriel Genellina

Mar 9 '07 #5
On Mar 9, 11:22 am, Erwan Adam <erwan.a...@cea.frwrote:
[snip]
>
[adam@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

Mar 9 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Clarence Gardner | last post by:
The super object is considered a solution to the "diamond problem". However, it generally requires that the ultimate base class know that it is last in the method resolution order, and hence it...
11
by: Nicolas Lehuen | last post by:
Hi, I hope this is not a FAQ, but I have trouble understanding the behaviour of the super() built-in function. I've read the excellent book 'Python in a Nutshell' which explains this built-in...
0
by: Delaney, Timothy C (Timothy) | last post by:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195 This is a new version of super that automatically determines which method needs to be called based on the existing stack frames....
3
by: gipsy boy | last post by:
Given a file descriptor (from a network socket, for instance), I want to have an iostream that reads/writes to it, so I can push and read data in the traditional way : sockStream << "<some...
9
by: Mike Krell | last post by:
I'm reading Alex Martelli's "Nutshell" second edition. In the section called "Cooperative superclass method calling", he presents a diamond inheritance hierachy: class A(object): def...
4
by: ddtl | last post by:
Hello everybody. Consider the following code: class A(object): def met(self): print 'A.met' class B(A): def met(self):
9
by: Raymond Hettinger | last post by:
I had an idea but no time to think it through. Perhaps the under-under name mangling trick can be replaced (in Py3.0) with a suitably designed decorator. Your challenge is to write the decorator....
3
by: Eric Mahurin | last post by:
Is there a standard way to get a descriptor object for an arbitrary object attribute - independent of whether it uses the descriptor/ property protocol or not. I want some kind of...
3
by: cyril giraudon | last post by:
Hello, I try to use python descriptors to define attributes with default value (the code is reported below). But apparently, it breaks the docstring mechanism. help(Basis) shows the right...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.