Fundamentals 8 min read

Creating Parameterized Decorators in Python: Logging, Performance, Authentication, Caching, and File Logging

This article demonstrates how to create various parameterized decorators in Python—including logging, performance measurement, authentication, caching, and file logging—by providing clear explanations and complete code examples for each use case in practical applications.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Creating Parameterized Decorators in Python: Logging, Performance, Authentication, Caching, and File Logging

Introduction In Python, writing decorators that accept parameters is an advanced technique that allows additional configuration such as log levels, cache sizes, or authentication rules. This guide presents five practical examples with full source code.

1. Parameterized Logging Decorator The log decorator receives a logging level and logs function entry and exit with the result.

import logging

def log(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            logging.log(level, f"Calling function '{func.__name__}'")
            result = func(*args, **kwargs)
            logging.log(level, f"Function '{func.__name__}' returned {result}")
            return result
        return wrapper
    return decorator

@log(logging.DEBUG)
def debug_function():
    return "Debug message"

@log(logging.INFO)
def info_function():
    return "Info message"

logging.basicConfig(level=logging.DEBUG)
debug_result = debug_function()
info_result = info_function()
print(debug_result)  # 输出:Debug message
print(info_result)   # 输出:Info message

In this example, the decorator accepts a log level and returns a proper decorator function.

2. Parameterized Performance Statistics Decorator The performance_stats decorator records execution time and call count, with a configurable precision.

import time

def performance_stats(precision=4):
    def decorator(func):
        call_count = 0
        total_time = 0.0
        def wrapper(*args, **kwargs):
            nonlocal call_count, total_time
            start_time = time.time()
            print(f"Calling function '{func.__name__}'")
            result = func(*args, **kwargs)
            end_time = time.time()
            elapsed_time = round(end_time - start_time, precision)
            total_time += elapsed_time
            call_count += 1
            print(f"Function '{func.__name__}' returned {result} in {elapsed_time:.{precision}f} seconds")
            print(f"Total calls: {call_count}, Total time: {total_time:.{precision}f} seconds")
            return result
        return wrapper
    return decorator

@performance_stats(precision=2)
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

result = factorial(5)
print(result)  # 输出:120

Here the decorator takes a precision argument and returns a proper decorator.

3. Parameterized Authentication Decorator The login_required decorator checks user credentials against an allowed‑users dictionary.

users = {
    "alice": "password123",
    "bob": "secret456"
}

def login_required(allowed_users):
    def decorator(func):
        def wrapper(username, password, *args, **kwargs):
            if username in allowed_users and allowed_users[username] == password:
                print(f"User '{username}' authenticated")
                return func(username, *args, **kwargs)
            else:
                print("Authentication failed")
                return None
        return wrapper
    return decorator

@login_required(users)
def view_profile(username):
    return f"Profile of user '{username}'"

result = view_profile("alice", "password123")
print(result)  # 输出:Profile of user 'alice'
result = view_profile("bob", "wrongpass")
print(result)  # 输出:None

The decorator receives a dictionary of allowed users and returns a proper decorator.

4. Parameterized Cache Decorator The memoize decorator caches function results with a configurable cache size.

from collections import OrderedDict

def memoize(cache_size=100):
    cache = OrderedDict()
    def decorator(func):
        def wrapper(*args, **kwargs):
            key = str(args) + str(kwargs)
            if key not in cache:
                print(f"Computing {func.__name__}({args}, {kwargs})")
                result = func(*args, **kwargs)
                cache[key] = result
                if len(cache) > cache_size:
                    cache.popitem(last=False)
            else:
                print(f"Retrieving {func.__name__}({args}, {kwargs}) from cache")
            return cache[key]
        return wrapper
    return decorator

@memoize(cache_size=10)
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

result = fibonacci(10)
print(result)  # 输出:55

This decorator accepts a cache size parameter and returns a proper decorator.

5. Parameterized File Logging Decorator The log_to_file decorator writes log messages to a specified file.

import logging

def log_to_file(log_file):
    logging.basicConfig(filename=log_file, level=logging.DEBUG, format='%(asctime)s %(message)s')
    def decorator(func):
        def wrapper(*args, **kwargs):
            logging.info(f"Calling function '{func.__name__}'")
            result = func(*args, **kwargs)
            logging.info(f"Function '{func.__name__}' returned {result}")
            return result
        return wrapper
    return decorator

@log_to_file("example.log")
def debug_function():
    return "Debug message"

debug_result = debug_function()
with open("example.log", "r") as file:
    log_content = file.read()
    print(log_content)

The decorator takes a log file name and returns a proper decorator.

Conclusion The article presented five parameterized decorator patterns—logging, performance measurement, authentication, caching, and file logging—each with clear explanations and complete, ready‑to‑run Python code, illustrating how decorators can be customized for diverse functional requirements.

PerformancePythoncachingLoggingauthenticationdecoratorparameterized
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.