super, decorators and gettattribute

Richard Szopa ryszard.szopa at gmail.com
Sat Jan 12 13:45:25 EST 2008


Hello all,

I am playing around w/ Python's object system and decorators and I
decided to write (as an exercise) a decorator that (if applied to a
method) would call the superclass' method of the same name before
doing anything (initially I wanted to do something like CLOS
[1] :before and :end methods, but that turned out to be too
difficult).

However, I cannot get it right (specially, get rid of the eval). I
suspect that I may be misunderstanding something happening between
super objects and __getattribute__ methods.

Here's my code:

def endmethod(fun):
    """Decorator to call a superclass' fun first.

    If the classes child and parent are defined as below, it should
    work like:

    >>> x = child()
    >>> x.foo()
    I am parent's foo
    I am child's foo.
    """
    name = fun.__name__
    def decorated(self, *args, **kwargs):
        try:
            super_object = super(self.__class__, self)

            # now I want to achieve something equivalent to calling
            # parent.foo(*args, **kwargs)
            # if I wanted to limit it only to this example

            # this doesn't work: in the example, it calls child's foo,
            # entering in an eternal loop (instead of calling parent's
            # foo, as I would expect).

            # super_object.__getattribute__(name)(*args, **kwargs)

            # this does work, but I feel it's ugly
            eval('super_object.%s(*args, **kwargs)' % name)
        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 parent(object):
    def foo(self):
        print 'I am parent\'s foo'

class child(parent):
    @endmethod
    def foo(self):
        print "I am foo\'s foo."

if __name__=='__main__':
    x = child()
    x.foo()

Can anybody tell me how to call a superclass method knowing its name?

Thanks in advance,
    -- Richard

[1] http://en.wikipedia.org/wiki/Common_Lisp_Object_System



More information about the Python-list mailing list