kze avatar

Useful Python Decorators

kze

Published: 10 Aug 2019 › Updated: 10 Aug 2019Useful Python Decorators

Useful Python Decorators

Python decorators are incredible useful for extending functions with other functionality.

import functools is required for each of these decorators.

Write results to file

def write_result_to_file(file, mode='w', encoding='utf-8', encoding_opts=[]):
    def decorator_write_result_to_file(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            result = func(*args, **kwargs)
            with open(file, mode) as f:
                if 'b' in mode and isinstance(result, str):
                    result = result.encode(encoding, *encoding_opts)
                f.write(result)
            return result
        return wrapper
    return decorator_write_result_to_file

Appending to a file the result of a function call

@write_result_to_file('test.txt', mode='a')
def do_something:
    return 42
a = do_something() # test.txt and a contain 42

Printing a functions run time

import time

def timer(func):
    """Print the runtime of the decorated function"""
    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()    # 1
        value = func(*args, **kwargs)
        end_time = time.perf_counter()      # 2
        run_time = end_time - start_time    # 3
        print(f"Finished {func.__name__!r} in {run_time:.4f} secs")
        return value
    return wrapper_timer

Capturing some debug info

def debug(func):
    """Print the function signature and return value"""
    @functools.wraps(func)
    def wrapper_debug(*args, **kwargs):
        args_repr = [repr(a) for a in args]                      # 1
        kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]  # 2
        signature = ", ".join(args_repr + kwargs_repr)           # 3
        print(f"Calling {func.__name__}({signature})")
        value = func(*args, **kwargs)
        print(f"{func.__name__!r} returned {value!r}")           # 4
        return value
    return wrapper_debug

Execute something after sleeping

def slow_down(seconds=1):
    """Sleep n seconds (or 1 second) before calling the function"""
    def decorator_slow_down(func):
        @functools.wraps(func)
        def wrapper_slow_down(*args, **kwargs):
            time.sleep(seconds)
            return func(*args, **kwargs)
        return decorator_slow_down
    return wrapper_slow_down

Execute multiple times

def repeat(num_times):
    def decorator_repeat(func):
        @functools.wraps(func)
        def wrapper_repeat(*args, **kwargs):
            for _ in range(num_times):
                value = func(*args, **kwargs)
            return value
        return wrapper_repeat
    return decorator_repeat

Leave Useful Python Decorators to:

Written by

Read more #python posts


Best Posts From kze

We have not curated any of kze's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From kze