A decorator factory is a function that returns a decorator function. It's called a factory because it produces a decorator based on the arguments passed to it.

Here's an example of a decorator factory that returns a timer decorator that accepts a message argument:

import time
 
def timer_factory(message):
    def timer_decorator(func):
        def wrapper(*args, **kwargs):
            start_time = time.monotonic()
            result = func(*args, **kwargs)
            end_time = time.monotonic()
            elapsed_time = end_time - start_time
            print(f"{message}: {elapsed_time:.6f} seconds")
            return result
        return wrapper
    return timer_decorator

In this example, the timer_factory function takes a message argument and returns a decorator that accepts a function as its argument. The returned decorator wraps the original function with timing code that measures the time it takes to execute the function and prints a message with the elapsed time.

Here's an example of how to use this decorator factory to time a function:

@timer_factory("Execution time")
def my_function():
    time.sleep(1)
 
my_function()

Output:

Execution time: 1.001394 seconds

In this example, the @timer_factory("Execution time") syntax applies the timer_decorator returned by the timer_factory function to the my_function function with the message "Execution time". When the function is called, the decorator will measure and print the execution time.

Note that the timer_factory function can be used to create multiple timer decorators with different messages. It's a powerful tool for creating reusable decorators with customizable behavior.