python中的装饰器(1)装饰器带参数

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

带参数的装饰器怎么用?(用大白话讲清楚)

装饰器就像给函数加个“外壳”,让它在执行时额外做些事情
但是,如果装饰器本身也需要参数,就得先告诉装饰器要怎么做,然后再装饰具体的函数
所以,带参数的装饰器要多一层嵌套,先拿到参数,再装饰函数。


🟢 举个例子:一个可以控制日志级别的装饰器

假设你有个 log(level) 装饰器:

  • 可以指定日志级别 (INFOWARNINGERROR)
  • 在执行函数前后打印日志
  • 让不同的函数可以选择不同的日志级别

📝 代码示例

import time

# 这是一个带参数的装饰器
def log(level="INFO"):  # ❶ 先接受参数
    def decorator(func):  # ❷ 这个才是真正的装饰器
        def wrapper(*args, **kwargs):  # ❸ 这个是包装函数
            print(f"[{level}] 开始执行 {func.__name__} ...")  # ❹ 记录日志
            start = time.perf_counter()
            result = func(*args, **kwargs)  # ❺ 执行原函数
            end = time.perf_counter()
            print(f"[{level}] {func.__name__} 执行完成,耗时 {end - start:.4f} 秒")  # ❻ 记录耗时
            return result  # ❼ 返回原函数的结果
        return wrapper  # ❽ 返回包装后的函数
    return decorator  # ❾ 返回装饰器

✅ 使用方法

1️⃣ 使用默认 INFO 级别
@log()  # 相当于 @log("INFO")
def add(a, b):
    time.sleep(1)  # 模拟计算
    return a + b

print(add(3, 5))

输出:

[INFO] 开始执行 add ...
[INFO] add 执行完成,耗时 1.0003 秒
8

✅ 这里 @log() 直接调用,默认是 INFO 级别。


2️⃣ 自定义 WARNING 级别
@log("WARNING")  # 传入参数,指定日志级别
def multiply(a, b):
    time.sleep(2)
    return a * b

print(multiply(4, 6))

输出:

[WARNING] 开始执行 multiply ...
[WARNING] multiply 执行完成,耗时 2.0005 秒
24

✅ 这里 @log("WARNING") 让日志显示 WARNING 级别。


🔍 解析代码执行过程

@log("WARNING") 装饰 multiply(a, b) 时,Python 发生了以下事情:

  1. 先执行 log("WARNING"),返回 decorator
  2. @decorator 作用在 multiply,返回 wrapper
  3. multiply(4, 6) 被调用时:
    • wrapper 先打印日志
    • 调用原函数 multiply(a, b)
    • 计算耗时
    • 继续打印日志

✅ 这就是为什么带参数的装饰器要多一层,因为它需要先接收参数,再装饰具体的函数


📌 总结

  1. 普通装饰器

    def decorator(func):
        def wrapper(*args, **kwargs):
            print("执行前")
            result = func(*args, **kwargs)
            print("执行后")
            return result
        return wrapper
    

    直接 @decorator 用,不需要额外传参。

  2. 带参数的装饰器

    def decorator_with_args(arg):
        def decorator(func):
            def wrapper(*args, **kwargs):
                print(f"参数: {arg}")
                return func(*args, **kwargs)
            return wrapper
        return decorator
    

    必须 @decorator_with_args(value) 先传参数,才能装饰函数。

📢 最通俗的比喻
普通装饰器直接穿衣服
带参数的装饰器先挑一件衣服(选参数),然后再穿上(装饰函数)

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值