[Tutor] Writing decorators?

Steven D'Aprano steve at pearwood.info
Wed Jul 20 08:03:57 EDT 2016

On Wed, Jul 20, 2016 at 09:33:19AM +0200, Michael Welle wrote:

> Somewhere in this thread (or the one talking about decorators after this
> thread) it was said that a decorator 'changes a function'. I not a
> native English speaker, so it could just be a language problem. But to
> me it seems the function is replaced, not changed?

It might have been me that used the term "changes a function".

A decorator can do anything. It can replace the function with a 
completely new one, ignoring the original function. It can wrap the 
original function in a closure, returning the wrapper. (The wrapper then 
calls the original function.) It can turn the function into a class, or 
a class into a function, or return something altogether different. It 
can modify the function and return it, or cause some side-effect and 
then return the original function with no changes made.

For example, here is a decorator that ensures that the function has a 
doc string, and inserts one if it doesn't:

def ensure_docstring(func):
    if func.__doc__ is None:
        func.__doc__ = "Please see the Fine Manual for '%s'" % func.__name__
    return func

def myfunc(args):

In this case, the function object is actually changed, not replaced.

The most common form of decorator wraps the original function inside a 
new function, as a closure, and returns the wrapper:

def decorate(func):
    def inner(*args):
        print("inside the wrapper")
        result = func(*args)
        print("original returns %r" % result)
        return result  # can modify the result
    return inner

Even though the decorator is returning a new function, the original is 
still hidden deep inside that "inner" function, as part of the closure, 
so in a sense, it is just a change to that original: it is *wrapped* in 
another function, which does some pre-processing or post-processing, but 
the original still does most of the work.

Does that help explain matters?


More information about the Tutor mailing list