On Jan 14, 1:53 pm, Michele Simionato <[EMAIL PROTECTED]> wrote: > I really need to publish this one day or another, since these > questions > about super keeps coming out: > > http://www.phyast.pitt.edu/~micheles/python/super.html
Thanks, Michele! Your essay was enlightening [2]. Specially if you take in account super's documentation is slightly outdated :). I also read Raymond Hettinger's article about descriptors (which you mention, but don't link to!) and decided to use them to reimplement methods that always call their superclass [1] method of the same name. Could you tell me what are the pros and cons of the two approaches (i.e. writing a decorator function and a decorator descriptor class)? The former gives slightly shorter code, while the second gives access to the original function and I somehow feel it is more... classy :) [code follows] Cheers, -- Richard [1] By which I mean the first class in their MRO. [2] I also found some other papers of yours about the "not for the faint of heart" corners of Python: MRO, metaclasses, class memoization, etc. and they were most enjoyable and interesting. def callingprevious1(fun): """Decorator to call a superclass' fun first. Decorator function approach. >>> class parent(object): ... def foo(self): ... print "I am foo of parent" ... >>> class child(parent): ... @callingprevious1 ... def foo(self): ... print "I am foo of child" ... >>> x = child() >>> x.foo() I am foo of parent I am foo of child >>> child.foo(x) I am foo of parent I am foo of child """ name = fun.__name__ def decorated(self, *args, **kwargs): try: super_object = super(self.__class__, self) getattr(super_object, name)(*args, **kwargs) except AttributeError: pass # if parent doesn't implement fun, we don't care # about it return fun(self, *args, **kwargs) # hopefully None decorated.__name__ = name return decorated class callingprevious(object): """ Decorator making the defined method call the method of the first superclass in mro at the beginning. Descriptor approach. >>> class parent(object): ... def foo(self): ... print "I am foo of parent" ... >>> class child(parent): ... @callingprevious ... def foo(self): ... print "I am foo of child" ... >>> x = child() >>> x.foo() I am foo of parent I am foo of child >>> child.foo(x) I am foo of parent I am foo of child """ def __init__(self, initval): self.name = initval.__name__ self.__combine_methods(initval) def __combine_methods(self, val): self.val = val def with_parent(obj, *args, **kwargs): try: parent_method = getattr(super(type(obj), obj), self.val.__name__) except AttributeError: pass else: parent_method(*args, **kwargs) return self.val(obj, *args, **kwargs) with_parent.__name__ = self.val.__name__ self.to_return = with_parent def __get__(self, obj, objtype): from types import MethodType # btw, is it anyhow better than just returning the function? return MethodType(self.to_return, obj, objtype) def __set__(self, obj, val): self.__combine_methods(val) -- http://mail.python.org/mailman/listinfo/python-list