百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

独家 | 让你的代码事半功倍——Python装饰器

off999 2024-12-03 00:12 19 浏览 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
55


2.@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

相关推荐

microsoft+teams+meeting怎么加入会议

teams手机点击加入会议没有反应原因和解决方法如下:1.时区不对,把电脑屏幕右下角时区调整好即可进入TeamsPC版。2.会议主办方的问题。3.MicrosoftTeams客户端的大多数问题都...

笔记本怎么设置wifi(笔记本怎么设置wifi密码)

笔记本电脑连接无线网络的具体设置步骤如下:1.打开电脑上的无线网络连接功能。在电脑屏幕下方中央区域找到网络连接图标,通常是两个悬挂的屏幕,点击打开。2.在网络连接列表中找到无线选项。一般无线选项图...

键盘所有按键都没反应(键盘无反应,鼠标正常)

台式机键盘失灵可以按以下四步来解决:1、重新插键盘与主机连接接口。有可能因为接口的接触不良导致的键盘失灵,这时可以对插头进行拔插,注意:如果是USB接口,可以直接插拔,而如果是圆形接头最好关机后再操作...

手机win10主题下载(手机windows11主题)

前面三位的方法都太复杂,还要找用户名什么。下面软件就搞定了,还可以自动提取Win10主题包里的壁纸。网页链接在软件上右键:一键打开主题目录,一键打开壁纸目录如果要提取主题包里的Win10壁纸,只要把主...

手机360助手有用吗

360手机助手是一款Android手机应用市场,由著名的安全软件厂商奇虎360公司开发和维护。它提供了丰富的应用程序下载、游戏下载、主题壁纸等资源,并且具备一定的应用管理和手机优化功能。360手机助手...

电脑主机频繁启动但启动不了

这个情况有可能是内存条换了,我上次就是这个情况,不知道怎么把内存条给烧了,然后它一給它插上电源就反复重启,刚一打开就自己又关上了反反复复。还有一次是因为这个电脑主机的电源插座的线换了,那个插头的口给烧...

用光盘重装电脑系统(用光盘重新安装系统)
  • 用光盘重装电脑系统(用光盘重新安装系统)
  • 用光盘重装电脑系统(用光盘重新安装系统)
  • 用光盘重装电脑系统(用光盘重新安装系统)
  • 用光盘重装电脑系统(用光盘重新安装系统)
win7怎么设置打印机共享(win7设置打印机共享没法用)
  • win7怎么设置打印机共享(win7设置打印机共享没法用)
  • win7怎么设置打印机共享(win7设置打印机共享没法用)
  • win7怎么设置打印机共享(win7设置打印机共享没法用)
  • win7怎么设置打印机共享(win7设置打印机共享没法用)
硬盘加密了怎么解除(硬盘加密了怎么解除密码)

一、打开“控制面板-系统和安全-BitLocker驱动器加密“,里面有关闭BitLocker加密;二、启动了win7系统自带的bitlocker功能,可以对磁盘进行加密;三、设置删除的话,打...

itunes驱动下载(itunes usb驱动)

安装方法如下:1、浏览器打开iTunes官网。2、在网站的右上方点击下载iTunes。3、在下载页面里点击立刻下载,下载后的iTunes会自动安装其驱动。4、点击保存,等待下载完成后点击运行。5、开始...

win10分辨率只有两个选项(win10分辨率就三个)

win10显示分辨率只有两种是因为显卡驱动安装不正确。解决办法:1、台式机电脑,检测电脑的显卡型号,如果为独立显卡,直接去显卡品牌的官方网下载相应型号的驱动程序的最新版;如果为集成显卡,建议去主板品牌...

cad序列号和密钥2014激活(cad序列号和密钥2014无效怎么办)

序列号:356-72378422,密钥:001F1AutoCAD2014需要本地注册运行,别人无法帮你算出受人以鱼不如受人以渔要关闭杀毒软件和助手(切记:如果是Vista或windows7系统,请务必...

电脑上下划线怎么打出来(电脑上下划线怎么打出来快捷键)

1.可以打开电脑中的word软件。然后在word软件中找到插入中的符号,并点击。2、点开符号,然后在符号中找到其它符号,并点击进入。3、在符号里面,可以直接找到下划线的按钮。4、接下来直接点击下划线的...

qq官网下载安卓手机版下载(qq官网下载最新版本下载)

苹果手机qq里传的软件安装方法如下:1、首先,我们打开手机上的qq软件。2、找到好友发送的软件链接,因为直接发安装文件,iOS没办法识别,无法安装。3、点击链接,我们跳转到appstore,点击允许...

win8安装应用商店(win8.1安装应用商店)

Windows11系统怎么重新安装应用商店,首先你要把你的电脑打开,然后连接上网络,使你的网络运行正常,这样你可以去电脑的浏览器里面。搜索应用商店,然后进行下载,下载成功以后,你可以根据系统的提示把...

取消回复欢迎 发表评论: