Python装饰器现在支持参数化吗

wen python案例 2

本文目录导读:

Python装饰器现在支持参数化吗

  1. 基本参数化装饰器结构
  2. 等效写法
  3. 更完整的例子
  4. 同时支持无参数调用
  5. 使用 functools.wraps 保持元数据

是的,Python装饰器完全支持参数化,参数化装饰器是通过嵌套多层函数实现的典型模式。

基本参数化装饰器结构

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator
@repeat(times=3)
def greet(name):
    print(f"Hello, {name}!")

等效写法

# 上面等同于:
greet = repeat(times=3)(greet)

更完整的例子

def add_logging(level="INFO"):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"[{level}] Calling {func.__name__}")
            result = func(*args, **kwargs)
            print(f"[{level}] {func.__name__} returned {result}")
            return result
        return wrapper
    return decorator
@add_logging(level="DEBUG")
def add(x, y):
    return x + y
add(2, 3)
# 输出:
# [DEBUG] Calling add
# [DEBUG] add returned 5

同时支持无参数调用

def log_or_repeat(func_or_times=None):
    if callable(func_or_times):
        # 无参数调用:@log_or_repeat
        @wraps(func_or_times)
        def wrapper(*args, **kwargs):
            print(f"Calling {func_or_times.__name__}")
            return func_or_times(*args, **kwargs)
        return wrapper
    else:
        # 有参数调用:@log_or_repeat(times=2)
        times = func_or_times or 1
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                for _ in range(times):
                    result = func(*args, **kwargs)
                return result
            return wrapper
        return decorator
# 两种用法都支持
@log_or_repeat
def say_hello():
    print("Hello!")
@log_or_repeat(times=3)
def say_hi():
    print("Hi!")

使用 functools.wraps 保持元数据

from functools import wraps
def validate(func=None, *, min_value=None, max_value=None):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for arg in args:
                if min_value is not None and arg < min_value:
                    raise ValueError(f"Argument {arg} is too small")
                if max_value is not None and arg > max_value:
                    raise ValueError(f"Argument {arg} is too large")
            return func(*args, **kwargs)
        return wrapper
    if func is None:
        return decorator  # 有参数调用
    return decorator(func)  # 无参数调用

参数化装饰器常用于权限控制、缓存、日志、性能监控等场景,非常灵活实用。

抱歉,评论功能暂时关闭!