Bootstrap

【python学习】装饰器的定义、特点和使用场景以及和闭包的区别

引言

装饰器在Python和其他支持类似特性的编程语言中非常有用,主要是因为它们提供了一种简单、优雅的方式来增加现有函数或方法的功能,而不需要修改其原始代码

一、装饰器的定义

装饰器(Decorator)在Python中是一个非常有用的功能,它允许程序员修改函数或方法的行为。装饰器本身是一个函数,它接收一个函数作为参数并返回一个新的函数。装饰器可以在不修改原始函数代码的情况下,增加原始函数的一些额外功能

二、装饰器的特点

2.1接受一个函数作为参数

装饰器本质上是一个高阶函数,它接受一个函数作为参数

2.2 返回一个新的函数

装饰器通常会返回一个新的函数,这个新函数将原始函数包裹在某种额外的逻辑中

2.3 可堆叠性

可以在一个函数上应用多个装饰器,装饰器会按照从内到外的顺序执行

2.4 不修改原始函数

装饰器不会修改原始函数的定义,而是创建了一个新的函数来扩展原始函数的行为

三、装饰器的使用场景

3.1 日志记录

记录函数调用的详细信息,如调用时间、参数、返回值等

3.2 性能测试

测量函数执行所需的时间

3.3 事务处理

确保函数执行过程中,如果发生异常可以回滚操作

3.4 权限校验

在执行函数之前检查用户权限

3.5 调试

在开发过程中,增加调试代码,如打印变量的值

3.6 注册函数

自动注册函数,以便在需要时可以找到它们

四、装饰器的示例

以下是一个简单的装饰器示例,用于测量函数执行的时间:

import time

def timer(func):
    def runtime():
        start_time = time.time()
        func()
        end_time = time.time()
        print('程序运行的时间是 %s 秒' % (end_time - start_time))
    return runtime

@timer
def sleep5():
    time.sleep(5)

sleep5() 

4.1 示例分析

4.1.1 导入模块:

import time

导入Python标准库中的time模块,它提供了各种与时间相关的功能

4.1.2 定义装饰器:

def timer(func):
    def runtime():
        start_time = time.time()
        func()
        end_time = time.time()
        print('程序运行的时间是 %s 秒' % (end_time - start_time))
    return runtime
  • timer 是一个装饰器函数,它接收一个函数 func 作为参数
  • timer 内部定义了一个嵌套函数 runtime,它将作为装饰器返回的新函数
  • runtime 函数执行以下步骤:
    1. 调用 time.time() 获取当前时间,并将其存储在 start_time 变量中
    2. 调用传入的 func 函数
    3. 再次调用 time.time() 获取当前时间,并将其存储在 end_time 变量中
    4. 打印出 func 函数执行所花费的时间,即 end_time 减去 start_time 的值

4.1.3 使用装饰器:

@timer
def sleep5():
    time.sleep(5)
  • @timer 是一个装饰器语法,它告诉Python在定义 sleep5 函数时应用 timer 装饰器
  • sleep5 是一个简单的函数,它调用 time.sleep(5),使程序暂停5秒钟

4.1.4 调用被装饰的函数:

sleep5()
  • 这行代码调用了被 timer 装饰器装饰过的 sleep5 函数
  • sleep5() 被调用时,实际上调用的是 timer 装饰器返回的 runtime 函数
  • runtime 函数执行,记录 sleep5 的执行时间,并打印出来

4.1.5 执行流程

  1. sleep5() 被调用时,实际上是 timer(sleep5) 返回的 runtime 函数被调用
  2. runtime 函数首先记录开始时间
  3. 然后调用原始的 sleep5 函数,该函数使程序暂停5秒钟
  4. sleep5 函数执行完毕后,runtime 函数记录结束时间
  5. 最后,runtime 函数计算并打印出 sleep5 函数的执行时间

4.1.6输出

运行这段代码时,输出将类似于以下内容:

程序运行的时间是 5.0023456789 秒

这个输出显示了 sleep5 函数的执行时间,由于 time.sleep(5) 暂停了5秒钟,所以打印出的时间接近5秒

五、总结(思维导图)

在这里插入图片描述

六、装饰器和闭包的区别

装饰器和闭包是Python中两个相关的概念,但它们有不同的用途和定义。下面是它们之间的主要区别

6.1 目的

闭包是为了封装和隐藏状态,而装饰器是为了在不修改原始函数的情况下增加额外功能

6.2 使用方式

闭包通常是通过函数字面量创建的,而装饰器是通过 @ 语法应用于函数

6.3 结构

闭包是内层函数,而装饰器是外层函数,装饰器内部通常会创建一个闭包

6.4 应用范围

闭包的概念更通用,而装饰器是Python特定的语法糖,用于特定的场景

简而言之,装饰器是闭包的一种应用,它利用闭包的特性来修改其他函数的行为。装饰器是闭包,但闭包不一定是装饰器

;