当前位置: 首页 > article >正文

【Python基础】Python 装饰器(优雅的代码增强工具)

本文收录于 《Python编程入门》专栏,从零基础开始,分享一些Python编程基础知识,欢迎关注,谢谢!

文章目录

    • 一、前言
    • 二、装饰器基础
    • 三、语法糖 @
    • 四、带参数的装饰器
    • 五、多层装饰器
    • 六、总结

一、前言

在Python编程的世界里,装饰器是一种独特且强大的工具,它允许程序员在不修改原函数代码的情况下,为函数添加新的功能或行为。

本文将带您探索装饰器的奥秘,看看它们是如何工作的,以及它们能为我们带来哪些便利。

  • 什么是Python?

    Python是由荷兰人吉多·范罗苏姆于1990年初设计的一门高级编程语言,该语言应用领域非常广泛,尤其在数据科学、人工智能、游戏开发等领域,它已经成为最受欢迎的程序设计语言之一,非常适合新手学习。

    Python语言标准库官方使用手册:https://docs.python.org/zh-cn/3/library/turtle.html#turtle-methods

  • Python语言有哪些特点?

    1.易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。

    2.易于阅读:Python代码定义的更清晰。

    3.易于维护:Python的成功在于它的源代码是相当容易维护的。

    4.丰富的库:Python的最大的优势之一具有丰富的标准库,并且跨平台的,在UNIX,Windows和Mac兼容很好。

    5.面向对象:Python支持面向对象编程,在“面向对象”的语言中,程序是由数据和功能组合而成的对象构建起来的。

    6.可移植:基于其开放源代码的特性,Python已经被移植(也就是使其工作)到许多平台。

    7.可扩展:如果你需要一段运行很快的关键代码,或者是想要编写一些不愿开放的算法,你可以使用C或C++完成那部分程序,然后从你的Python程序中调用。

    8.可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"的能力。

    在这里插入图片描述

二、装饰器基础

装饰器本质上是一个函数,它接受另一个函数作为参数,并返回一个新的函数。这个新的函数通常在原函数的基础上增加了一些额外的行为。

例如,我们有一个简单的函数 foo():

def foo():
    print('hello foo')

如果我们希望在调用 foo() 时记录函数的执行时间,可以使用装饰器,如下:

import time

# 定义一个装饰器函数,记录执行时间
def show_time(func):
    def wrapper():
        start_time = time.time()
        func()
        end_time = time.time()
        duration = end_time - start_time
        print(f"函数 {func.__name__} 执行时间为:{duration:.3f} 秒")
    return wrapper

# 调用装饰器函数,记录执行时间
@show_time
def foo():
    print('hello foo')
    time.sleep(3)

foo()

"""
输出:
hello foo
函数 foo 执行时间为:3.002 秒
"""

在上述例子中,show_time 是一个装饰器,它接受函数 foo 作为参数,并返回一个新的函数 wrapper。wrapper 函数在调用 func() 前后记录时间,从而实现了在不修改 foo 函数代码的情况下,增加了时间记录的功能。

三、语法糖 @

Python 提供了 @ 语法糖来简化装饰器的使用。在定义 foo 函数时使用 @show_time,避免了显式地将 foo 函数传递给 show_time 并赋值的步骤,如下:

# 使用@ 语法糖方式,调用装饰器函数,记录执行时间
@show_time
def foo():
    print('hello foo')
    time.sleep(3)

四、带参数的装饰器

有时我们希望装饰器能够接收参数,以便根据不同的需求进行定制。

例如,我们希望根据标志决定是否将执行时间记录到日志中。

import time

# 定义一个装饰器函数,记录执行时间
def time_logger(flag):
    def show_time(func):
        def wrapper():
            start_time = time.time()
            func()
            end_time = time.time()
            duration = end_time - start_time
            print(f"函数 {func.__name__} 执行时间为:{duration:.3f} 秒")
            if flag:
                print('将这个操作的时间记录到日志中')
        return wrapper
    return show_time

# 调用装饰器函数,记录执行时间
@time_logger(flag=True)
def foo():
    print('hello foo')
    time.sleep(3)

foo()

"""
输出
hello foo
函数 foo 执行时间为:3.013 秒
将这个操作的时间记录到日志中

"""

在这个例子中,time_logger 是一个带有参数的装饰器,它返回一个内部装饰器 show_time。通过 @time_logger(flag=True),我们可以在不修改 bar 函数代码的前提下,根据 flag 的值来决定是否记录日志。

五、多层装饰器

多层装饰器允许我们在函数上应用多个装饰器,从而实现更复杂的功能。装饰器的执行顺序是从最外层向内层执行,而调用顺序则相反,从内层向外层执行。

例如:

# 定义装饰器make_bold
def make_bold(func):
    def wrapper():
        return "<b>" + func() + "</b>"
    return wrapper

# 定义装饰器make_italic
def make_italic(func):
    def wrapper():
        return "<i>" + func() + "</i>"
    return wrapper

# 使用装饰器make_bold和装饰器make_italic
@make_bold
@make_italic
def hello():
    return "hello alvin"

print(hello())  # 输出:<b><i>hello alvin</i></b>

在上述例子中,hello 函数先被 make_italic 装饰,再被 make_bold 装饰。因此,hello() 的返回值首先被 make_italic 包裹,再被 make_bold 包裹。

六、总结

Python 装饰器是一种优雅的代码增强工具,它允许我们在不修改原函数代码的情况下,为函数添加额外的功能。装饰器广泛应用于日志记录、性能测试、事务处理、缓存和权限校验等场景。掌握装饰器的使用,可以显著提高代码的复用性和可读性,使程序设计更加灵活和模块化。

如果您对文章中内容有疑问,欢迎在评论区进行留言,我会尽量抽时间给您回复。如果文章对您有帮助,欢迎点赞、收藏。您的点赞,是对我最大的支持和鼓励,谢谢 :-)


http://www.kler.cn/news/307198.html

相关文章:

  • 如何通过Chrome浏览器轻松获取视频网站的TS文件
  • 什么是交换机级联?
  • 使用Python生成多种不同类型的Excel图表
  • HTML5元素定位
  • 小米,B站网络安全岗位笔试题目+答案
  • 借老系统重构我准备写个OpenAPI3.1版的API管理工具(附录屏演示)
  • 快手自研Spark向量化引擎正式发布,性能提升200%
  • MySQL基础(11)- 创建管理表
  • bug 记录 - animation 在 IOS机型掉帧情况
  • Web安全之HTTPS调用详解和证书说明案例示范
  • Ubuntu 安装包下载(以20版本 阿里镜像站为例子)
  • 非凸科技钻石赞助第四届Rust China Conf 2024
  • (南京观海微电子)——GH7006+Boe_6.8_AV068WVU-N10原理介绍
  • 数据清洗-缺失值填充-K-NN算法(K-Nearest Neighbors, K-NN算法)
  • STM32与ESP8266的使用
  • SSH工具 MobaXterm的使用与快捷配置
  • 【JS|第27期】网页文件传输:Blob与Base64的对决
  • 优化理论及应用精解【8】
  • 视频生成3D模型luma AI Dashboard
  • shell脚本中sed命令如何使用变量
  • 开发适合el-dialog的拉伸拖拽自定义指令和适配自定义的图片查看组件
  • 从主流技术架构视角剖析 Java Web 项目的性能测试策略与挑战
  • 研1日记13
  • unity3d入门教程六
  • 校验(网络传输)
  • PHP环境搭建
  • 函数模板(初阶)
  • VuePress搭建文档网站/个人博客(详细配置)之站点配置
  • 海鲜市场|基于springboot的网络海鲜市场系设计与实现(附项目源码+论文+数据库)
  • item_get京东获取商品详情SKU数据接口||关于京东商品采集接口