Gabriel Genellina a écrit : > En Fri, 09 Mar 2007 06:25:08 -0300, Erwan Adam <[EMAIL PROTECTED]> > 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 : [EMAIL PROTECTED] /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. -- http://mail.python.org/mailman/listinfo/python-list