function decorators

Ian Kelly ian.g.kelly at gmail.com
Tue Sep 28 18:28:21 EDT 2010


On Tue, Sep 28, 2010 at 4:02 PM, Nick Donohue <ndonohue at gmail.com> wrote:

> I came across this code just now:
>
> def time_me(function):
>  def wrap(*arg):
>    start = time.time()
>    r = function(*arg)
>    end = time.time()
>    print "%s (%0.3f ms)" %(function.func_name, (end-start)*1000)
>  return wrap
>
> @time_me
> def some_function(somearg)
>
> some_function(arg)
>
> I've been looking online about what I think is going on, and from what
> I can tell this code is using function decorators.
>
> I guess what I'm asking is if someone could tell me what exactly is
> going on in this code - how is it different from passing:
> time_me(some_function(123))? I've tried it this way and it works.
>

Not quite.  It's actually equivalent to calling time_me(some_function)(123).


> why would I use these? wouldn't it be more flexible to not write the
> decorator before the function definition, so I could choose to wrap it
> or not?
>

In general, yes.  In the particular case above, I don't know why it would
have been written as a decorator, unless it was merely meant to be toy
code.  Generally I'll use a decorator in order to add common functionality
that is critical to the function's operation.  Dynamically adding a default
keyword argument is one example that comes to mind, or wrapping the function
in a context manager without adding indentation to the entire function body.

Also, decorators can also be used for things besides wrapping functions,
such as registering them with a framework.

Cheers,
Ian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20100928/b51cd423/attachment.html>


More information about the Python-list mailing list