decorator peculiarity

Diez B. Roggisch deetsNOSPAM at web.de
Fri Dec 17 09:01:31 EST 2004


Hi,

I just wrote my first decorator example - and  I already love them.

However I've encountered one peculiarity that strikes me odd:

When one writes a decorated function like this:

@decorate
def foo():
    pass

the function decorate usually looks like this:

def decorate(func):
    def _d(*args, **kwargs):
        do_something()
        # call func
        func(*args, **kwargs)
    return _d

So the function decorator has to return a function that is bound to the name
foo in the originating context (module or class) and gets the function
passed as argument.

But if I want my decorator to be parametrized, it looks like this:

@decorate(arg)
def foo():
    pass

def decorate(arg):
    def f(func):
        def _d(*args, **kwargs):
            do_something(arg)
            # call func
            func(*args, **kwargs)
        return _d

So what happens is that an decorater with arguments is called with these,
returns a callable that then is called with foo, and the result is stored
under foo.

Now why this layer of indirection? I would have supposed that things look
like this:


def decorate(func, arg):
    def _d(*args, **kwargs):
        do_something(arg)
        # call func
        func(*args, **kwargs)
    return _d

A sideeffect of this behaviour is that for a fully keyword-argumentized
function I still have to write parentheses:

@decorate()
def foo():
    pass

def decorate(arg=None):
    def f(func):
        def _d(*args, **kwargs):
            do_something(arg)
            # call func
            func(*args, **kwargs)
        return _d

I don't mind the extra parentheses too much - it just made me wonder what
the rationale behind this is.

-- 
Regards,

Diez B. Roggisch



More information about the Python-list mailing list