登录
首页 >  文章 >  python教程

带参数的Python装饰器怎么写?

时间:2026-05-16 18:49:15 301浏览 收藏

带参数的Python装饰器本质上是一个“返回装饰器的函数”,通过三层嵌套结构灵活接收配置参数(如日志级别、重试次数),在不侵入原函数逻辑的前提下动态增强功能;文中以`@logger("info")`和`@retry(max_attempts=2)`为例,清晰展示了如何构建可配置、可复用且保留函数元信息(借助`functools.wraps`)的实用装饰器,让代码更简洁、健壮且专业。

python带参数的装饰器怎么写?

带参数的装饰器其实是一个返回装饰器的函数。也就是说,它外层多了一层函数包装,用来接收参数。

基本结构说明

要写一个带参数的装饰器,你需要三层嵌套函数:

  • 最外层函数:接收装饰器的参数
  • 中间层函数:接收被装饰的函数
  • 最内层函数:实际执行逻辑,可以调用原函数并添加额外行为

示例:一个记录日志级别的装饰器

比如你想控制打印日志的级别(info、warning等):

def logger(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"[{level.upper()}] 正在执行 {func.__name__}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

# 使用
@logger("info")
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

输出:

[INFO] 正在执行 say_hello
Hello, Alice!

使用 functools.wraps 保留原函数信息

为了不丢失原函数的元数据(如 __name__、__doc__),建议加上 functools.wraps

from functools import wraps

def logger(level):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print(f"[{level.upper()}] 正在执行 {func.__name__}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@logger("debug")
def test():
    """测试函数"""
    print("running test")

print(test.__name__)  # 输出: test(没被wrapper覆盖)
print(test.__doc__)   # 输出: 测试函数

支持多种参数的实用例子

比如限制函数重试次数的装饰器:

def retry(max_attempts=3):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for i in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f"第 {i+1} 次尝试失败: {e}")
                    if i == max_attempts - 1:
                        raise
        return wrapper
    return decorator

@retry(max_attempts=2)
def may_fail():
    import random
    if random.random() < 0.8:
        raise ConnectionError("网络错误")
    print("成功!")

# 可能重试一次后成功
may_fail()

基本上就这些。关键点是:带参数的装饰器 = 函数返回装饰器。结构清晰,层层嵌套,配合 wraps 更专业。

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《带参数的Python装饰器怎么写?》文章吧,也可关注golang学习网公众号了解相关技术文章。

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>