DEV Community

Python Decorator Tutorial with Example

Apcelent on July 09, 2018

If you want to take a really deep dive, you should read these exhaustive articles by Graham Dumpleton. However, if you intend to get started and ge...
Collapse
 
otacilion profile image
Otacilio Saraiva Maia Neto

In this piece of code:

    def inner_function(function):
    @wraps(function)
    def wrapper(*args, **kwargs):
        print "Arguements passed to decorator %s and %s" % (arg1, arg2)
        function(*args, **kwargs)
    return wrapper
    return inner_function
Enter fullscreen mode Exit fullscreen mode


`
is it missing some identation?

Collapse
 
sp1thas profile image
Panagiotis Simakis

Good catch! I'm pretty sure that should look like:

def decorator(arg1, arg2):

    def inner_function(function):
        @wraps(function)
        def wrapper(*args, **kwargs):
            print "Arguements passed to decorator %s and %s" % (arg1, arg2)
            function(*args, **kwargs)
        return wrapper
    return inner_function
Enter fullscreen mode Exit fullscreen mode
Collapse
 
vberlier profile image
Valentin Berlier • Edited

There's also the pattern with functools.partial that allows you to call decorators with optional arguments without the parenthesis if you want to use the default values.

from functools import partial, wraps

def print_result(func=None, *, prefix=''):
    if func is None:
        return partial(print_result, prefix=prefix)

    @wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print(f'{prefix}{result}')
        return result
    return wrapper

Now you can apply the decorator without the parenthesis if you want to use the default value.

@print_result
def add(a, b):
    return a + b

add(2, 3)  # outputs '5'

@print_result()
def add(a, b):
    return a + b

add(2, 3)  # outputs '5'

@print_result(prefix='The return value is ')
def add(a, b):
    return a + b

add(2, 3)  # outputs 'The return value is 5'

There's no way of getting it wrong when you apply the decorator. IMO it's the simplest and most readable pattern. I use it all the time.

Collapse
 
djangotricks profile image
Aidas Bendoraitis

Looks like a useful article. But can you please correct the indentation of the Python code?

Collapse
 
andrejhatzi profile image
Andrej Hatzi

timed does not exist, maybe thou should test the code before posting it!