[Python-Dev] Adding functools.decorator
Nick Coghlan
ncoghlan at gmail.com
Tue May 2 12:36:42 CEST 2006
Guido van Rossum wrote:
> On 4/30/06, Georg Brandl <g.brandl at gmx.net> wrote:
>> Guido van Rossum wrote:
>>> I expect that at some point people will want to tweak what gets copied
>>> by _update_wrapper() -- e.g. some attributes may need to be
>>> deep-copied, or personalized, or skipped, etc.
>> What exactly do you have in mind there? If someone wants to achieve this,
>> she can write his own version of @decorator.
>
> I meant that the provided version should make writing your own easier
> than copying the source and editing it. Some form of subclassing might
> make sense, or a bunch of smaller functions that can be called for
> various actions. You'll probably have to discover some real use cases
> before you'll be able to design the right API for this.
Maybe we should just expose a basic interface to replace the four lines of
boilerplate (the docstring makes this look more complicated than it really is!):
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
WRAPPER_UPDATES = ('__dict__')
def update_wrapper(wrapper, wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
"""Update a wrapper function to look like the wrapped function
Attributes of the wrapped function named in the assigned
argument are assigned directly to the corresponding attributes
of the wrapper function.
The update() method of wrapper function attributes named in the
updated argument are called with the corresponding attribute of
the wrapped function as their sole argument.
"""
for attr in assigned:
setattr(wrapper, attr, getattr(wrapped, attr))
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr))
The two global constants provide clear documentation of the default behaviour
and the keyword arguments make it easy to copy or update a couple of extra
arguments if you need to, or to prevent the standard copying.
Including the return statement allows this to be used as a decorator if you
prefer:
from functools import partial, update_wrapper
@partial(update_wrapper, func)
def wrapper(*args, **kwds):
# wrap func here.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-Dev
mailing list