Tips and Tricks - Flexible Decorators

Since Python 3.9, decorators are a lot more flexible than before. Any callable can now be a decorator. With that being said, a couple of (seen from the perspective of a Python 3.8 developer) crazy things can be done.

Suppose we have three decorators transforming the returned text of a given function:

import functools

def normal(func):
    return func

def shout(func):
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs).upper()

    return wrapper

def whisper(func):
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs).lower()

    return wrapper

From Python 3.9 onwards, we can put all three into a dictionary, let the user decide, which one to use, and apply it to a given function as follows:

# previous code in
    "normal": normal,
    "shout": shout,
    "whisper": whisper,

voice = input(f"Choose your voice ({', '.join(DECORATORS)}):")

def get_story():
    return "This is a sample text."


Executing the script at hand gives us the following output:

$ python
Choose your voice (normal, shout, whisper): shout

Groups: language reference