【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 装饰器是一种优雅的代码增强工具,它允许我们在不修改原函数代码的情况下,为函数添加额外的功能。装饰器广泛应用于日志记录、性能测试、事务处理、缓存和权限校验等场景。掌握装饰器的使用,可以显著提高代码的复用性和可读性,使程序设计更加灵活和模块化。
如果您对文章中内容有疑问,欢迎在评论区进行留言,我会尽量抽时间给您回复。如果文章对您有帮助,欢迎点赞、收藏。您的点赞,是对我最大的支持和鼓励,谢谢 :-)