More decorator rumination

Peter Otten __peter__ at web.de
Thu Mar 31 10:18:28 CEST 2005


Scott David Daniels wrote:

> In particular, I thought about something like:
> 
> @mousexy
> def OnRightClick(self, x, y):
> ...

You could somewhat generalize the idea -- have one argument in the wrapper
function provide the arguments missing in the wrapped one.

Here is a self-contained example, for the moment without support for keyword
arguments:

import inspect

class Event:
    _x, _y, buttons = 1, 2, 3
    def getX(self): return self._x
    def getY(self): return self._y

_getter_for_name = dict(
    x=Event.getX, 
    y=Event.getY, 
    buttons=lambda e: e.buttons
    )

def event(fun):
    getters = [_getter_for_name.get(arg) for arg in inspect.getargspec(fun
[0]]
    def wrapped(*args):
        # the Event instance must be the last argument
        event = args[-1]
        expanded = [get(event) for get in getters[len(args)-1:]] 
        args = args[:-1] + tuple(expanded)
        return fun(*args)
    return wrapped

class Alpha:
    @event
    def alpha(self, x):
        print "--alpha--"
        print "x =", x

    @event
    def beta(self, x, buttons):
        print "--beta--"
        print "x =", x
        print "buttons =", buttons

@event
def gamma(buttons, y, x):
    print "--gamma--"
    print "x =", x
    print "y =", y
    print "buttons =", buttons

a = Alpha()
a.alpha(Event())
a.beta(Event())    
gamma(Event())
# only the x argument will be set 
# by the decorator (to Event().getX())
gamma("BUTTONS", "Y", Event())

Peter




More information about the Python-list mailing list