独家 | 让你的代码事半功倍——Python装饰器
off999 2024-12-03 00:12 24 浏览 0 评论
作者: Ayush Thakur
翻译:王可汗校对:潘玏妤本文约2400字,建议阅读5分钟
本文介绍了用Python装饰器的基本概念和示例。
大家好,欢迎来到我的博客!今天我将与大家分享一些神奇的Python装饰器,它们可以将你的代码量减少一半。听起来太好了,不过这是真的,对吧?那么,让我向你展示它们是如何工作的,以及为什么你应该在你的项目中使用它们。
什么是Python装饰器?
Python装饰器是一种强大的功能,它允许你修改函数或类的行为,而不更改其源代码。实质上,装饰器是接受另一个函数作为参数并返回一个包装原始函数的新函数。这样,你可以在不修改原始函数的情况下,添加一些额外的功能或逻辑。
举个例子,假设你有一个函数,它将消息打印到控制台:
def hello():
print("Hello, world!")现在,假设你想要计算执行该函数所需的时间。你可以编写另一个函数,使用time模块来计算执行时间,然后调用原始函数:
importtime
def measure_time(func):
def wrapper():
start = time.time()
func()
end = time.time()
print(f"Execution time: {end - start} seconds")
return wrapper请注意,measure_time函数返回另一个名为wrapper的函数,这个函数是原始函数的修改版本。wrapper函数有两个作用:记录执行的开始时间和结束时间,以及调用原始函数。
现在,要使用这个函数,你可以这样做:
hello = measure_time(hello)
hello()这将输出如下内容:
Hello, world!
Execution time: 0.000123456789 seconds正如你所看到的,我们成功地添加了一些额外的功能到hello函数中,而无需更改其代码。然而,使用装饰器有一种更优雅且更简洁的方式来实现这一点。装饰器只是使用`@`符号将一个函数应用到另一个函数的语法糖。例如,我们可以将上述代码重写为:
@measure_time
def hello():
print("Hello, world!")
hello()这将产生与之前相同的输出结果,但需要的代码更少。@measure_time这一行等同于hello = measure_time(hello),但看起来更简洁和易读。
为什么要使用python装饰器呢?
使用Python装饰器的好处有很多,例如:
¨它们允许你重复使用代码,避免冗余。例如,如果你有很多需要计算执行时间的函数,你可以简单地将相同的装饰器应用到它们上,而不是一遍遍地编写相同的代码。
¨它们允许你将关注点分离,并遵循单一职责原则。例如,如果你有一个执行一些复杂计算的函数,你可以使用装饰器处理日志记录、错误处理、缓存或输入输出验证,而不会将主要逻辑混杂其中。
¨它们允许你在不修改源代码的情况下扩展现有函数或类的功能。例如,如果你正在使用第三方库提供的一些有用的函数或类,但你想要为它们添加一些额外的功能或行为,你可以使用装饰器来包装它们,并按需进行自定义。
一些Python装饰器的例子
Python中有许多内置的装饰器,例如@staticmethod、@classmethod、@property、@functools.lru_cache、@functools.singledispatch等。你还可以为不同的目的创建自己的自定义装饰器。以下是一些可以帮助你精简代码的Python装饰器示例:
1.@timer装饰器
这个装饰器类似于之前我们见过的@measure_time装饰器,但它可以应用于任何接受任意数量参数并返回任意值的函数。它还使用functools.wraps装饰器来保留原始函数的名称和文档字符串。以下是代码示例:
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"Execution time of {func.__name__}: {end - start} seconds")
return result
return wrapper
现在,您可以使用此装饰器来测量任何函数的执行时间,例如:
@timer
def factorial(n):
"""Returns the factorial of n"""
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
@timer
def fibonacci(n):
"""Returns the nth Fibonacci number"""
if n == 0 or n == 1:
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(factorial(10))
print(fibonacci(10))这将输出如下内容:
Execution time of factorial: 1.1920928955078125e-06 seconds
3628800
Execution time of fibonacci: 0.000123456789 seconds
552.@debug装饰器
这个装饰器用于调试目的,因为它会打印包装的函数的名称、参数和返回值。它还使用了functools.wraps装饰器来保留原始函数的名称和文档字符串。以下是代码示例:
from functools import wraps
def debug(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with args: {args} and kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned: {result}")
return result
return wrapper现在,您可以使用此装饰器来调试任何函数,例如:
@debug
def add(x, y):
"""Returns the sum of x and y"""
return x + y
@debug
def greet(name, message="Hello"):
"""Returns a greeting message with the name"""
return f"{message}, {name}!"
print(add(2, 3))
print(greet("Alice"))
print(greet("Bob", message="Hi"))
这将输出如下内容:
Calling add with args: (2, 3) and kwargs: {}
add returned: 5
5
Calling greet with args: ('Alice',) and kwargs: {}
greet returned: Hello, Alice!
Hello, Alice!
Calling greet with args: ('Bob',) and kwargs: {'message': 'Hi'}
greet returned: Hi, Bob!
Hi, Bob!3.@memoize装饰器
这个装饰器对于优化递归或耗时函数的性能非常有用,因为它会缓存先前调用的结果,并在再次传递相同参数时返回它们。它还使用functools.wraps装饰器来保留原始函数的名称和文档字符串。以下是代码示例:
from functools import wraps
def memoize(func):
cache = {}
@wraps(func)
def wrapper(*args):
if args in cache:
return cache[args]
else:
result = func(*args)
cache[args] = result
return result
return wrapper现在,您可以使用此装饰器来对任何函数进行记忆化处理,例如:
@memoize
def factorial(n):
"""Returns the factorial of n"""
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
@memoize
def fibonacci(n):
"""Returns the nth Fibonacci number"""
if n == 0 or n == 1:
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(factorial(10))
print(fibonacci(10))这将输出与之前相同的结果,但执行时间更快,因为结果被缓存并重复使用。
结论
Python装饰器是一种强大而优雅的方式,可以在不更改函数或类的源代码的情况下修改它们的行为。它们可以帮助您减少代码量,改善代码可读性,重复使用代码,分离关注点以及扩展现有代码的功能。希望您喜欢这篇博客文章并学到了一些新知识。如果您有任何问题或意见,请随时在下方留言。并且不要忘记与您的朋友和同事们分享这篇文章,他们可能对学习更多关于Python装饰器的知识感兴趣。感谢您的阅读!
原文标题:
Python Decorators That Can Reduce Your Code By Half
原文链接:
https://medium.com/@ayush-thakur02/python-decorators-that-can-reduce-your-code-by-half-b19f673bc7d8
相关推荐
- 安全教育登录入口平台(安全教育登录入口平台官网)
-
122交通安全教育怎么登录:122交通网的注册方法是首先登录网址http://www.122.cn/,接着打开网页后,点击右上角的“个人登录”;其次进入邮箱注册,然后进入到注册页面,输入相关信息即可完...
- 大鱼吃小鱼经典版(大鱼吃小鱼经典版(经典版)官方版)
-
大鱼吃小鱼小鱼吃虾是于谦跟郭麒麟的《我的棒儿呢?》郭德纲说于思洋郭麒麟作诗的相声,最后郭麒麟做了一首,师傅躺在师母身上大鱼吃小鱼小鱼吃虾虾吃水水落石出师傅压师娘师娘压床床压地地动山摇。...
-
- 哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)
-
要想将ppt免费转换为pdf的话,我们建议大家可以下一个那个wps,如果你是会员的话,可以注册为会员,这样的话,在wps里面的话,就可以免费将ppt呢转换为pdfpdf之后呢,我们就可以直接使用,不需要去直接不需要去另外保存,为什么格式转...
-
2026-02-04 09:03 off999
- 电信宽带测速官网入口(电信宽带测速官网入口app)
-
这个网站看看http://www.swok.cn/pcindex.jsp1.登录中国电信网上营业厅,宽带光纤,贴心服务,宽带测速2.下载第三方软件,如360等。进行在线测速进行宽带测速时,尽...
- 植物大战僵尸95版手机下载(植物大战僵尸95 版下载)
-
1可以在应用商店或者游戏平台上下载植物大战僵尸95版手机游戏。2下载教程:打开应用商店或者游戏平台,搜索“植物大战僵尸95版”,找到游戏后点击下载按钮,等待下载完成即可安装并开始游戏。3注意:确...
- 免费下载ppt成品的网站(ppt成品免费下载的网站有哪些)
-
1、Chuangkit(chuangkit.com)直达地址:chuangkit.com2、Woodo幻灯片(woodo.cn)直达链接:woodo.cn3、OfficePlus(officeplu...
- 2025世界杯赛程表(2025世界杯在哪个国家)
-
2022年卡塔尔世界杯赛程公布,全部比赛在卡塔尔境内8座球场举行,2022年,决赛阶段球队全部确定。揭幕战于当地时间11月20日19时进行,由东道主卡塔尔对阵厄瓜多尔,决赛于当地时间12月18日...
- 下载搜狐视频电视剧(搜狐电视剧下载安装)
-
搜狐视频APP下载好的视频想要导出到手机相册里方法如下1、打开手机搜狐视频软件,进入搜狐视频后我们点击右上角的“查找”,找到自已喜欢的视频。2、在“浏览器页面搜索”窗口中,输入要下载的视频的名称,然后...
- 永久免费听歌网站(丫丫音乐网)
-
可以到《我爱音乐网》《好听音乐网》《一听音乐网》《YYMP3音乐网》还可以到《九天音乐网》永久免费听歌软件有酷狗音乐和天猫精灵,以前要跳舞经常要下载舞曲,我从QQ上找不到舞曲下载就从酷狗音乐上找,大多...
- 音乐格式转换mp3软件(音乐格式转换器免费版)
-
有两种方法:方法一在手机上操作:1、进入手机中的文件管理。2、在其中选择“音乐”,将显示出手机中的全部音乐。3、点击“全选”,选中所有音乐文件。4、点击屏幕右下方的省略号图标,在弹出菜单中选择“...
- 电子书txt下载(免费的最全的小说阅读器)
-
1.Z-library里面收录了近千万本电子书籍,需求量大。2.苦瓜书盘没有广告,不需要账号注册,使用起来非常简单,直接搜索预览下载即可。3.鸠摩搜书整体风格简洁清晰,书籍资源丰富。4.亚马逊图书书籍...
- 最好免费观看高清电影(播放免费的最好看的电影)
-
在目前的网上选择中,IMDb(互联网电影数据库)被认为是最全的电影网站之一。这个网站提供了各种类型的电影和电视节目的海量信息,包括剧情介绍、演员表、评价、评论等。其还提供了有关电影制作背后的详细信息,...
- 孤单枪手2简体中文版(孤单枪手2简体中文版官方下载)
-
要将《孤胆枪手2》游戏的征兵秘籍切换为中文,您可以按照以下步骤进行操作:首先,打开游戏设置选项,通常可以在游戏主菜单或游戏内部找到。然后,寻找语言选项或界面选项,点击进入。在语言选项中,选择中文作为游...
欢迎 你 发表评论:
- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
