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

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

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部