装饰器:Python代码更上一层楼

本文介绍了12个实用的Python装饰器,包括@logger、@wraps、@lru_cache、@repeat等,这些装饰器可增强代码功能,如日志记录、性能跟踪、缓存、重试机制等。通过使用装饰器,Python开发者能写出更简洁、高效的代码。
摘要由CSDN通过智能技术生成

Python 装饰器是强大的工具,可帮助您生成干净、可重用和可维护的代码。在不影响质量的情况下,用更少的代码做更多的事情

我等了很久才想了解这些抽象,现在我已经有了扎实的理解,我写这个故事作为实用指南,也可以帮助您掌握这些对象背后的概念。

今天没有大的介绍或冗长的理论定义。

这篇文章是我经常在我的项目中使用的 12 个有用的装饰器的文档列表,以使用额外的功能扩展我的代码。我们将深入研究每个装饰器,查看代码并尝试一些动手示例。

如果您是 Python 开发人员,这篇文章将使用有用的脚本扩展您的工具箱,以提高您的工作效率并避免代码重复。

话不多说,我建议我们现在就进入代码💻

1 — @logger(开始)✏️ 

如果您不熟悉装饰器,您可以将它们视为将函数作为输入并在不改变其主要用途的情况下扩展其功能的函数。

让我们从一个简单的装饰器开始,它通过记录函数开始和结束执行的时间来扩展函数。

被修饰的函数的结果如下所示:

some_function(args)

# ----- some_function: 开始 ----- 
# some_function 执行
# ----- some_function: 结束 -----

编写 decroator,您首先必须选择一个合适的名称:我们称它为logger

logger是一个函数,它将一个函数作为输入并返回一个函数作为输出。输出函数通常是输入的扩展版本。start在我们的例子中,我们希望输出函数用and语句包围输入函数的调用end

由于我们不知道输入函数使用什么参数,我们可以使用*args**kwargs从包装函数传递它们。这些表达式允许传递任意数量的位置参数和关键字参数。

下面是装饰器的一个简单实现logger

def logger(function):
    def wrapper(*args, **kwargs):
        print(f"----- {function.__name__}: start -----")
        output = function(*args, **kwargs)
        print(f"----- {function.__name__}: end -----")
        return output
    return wrapper

现在您可以将记录器应用到some_function或任何其他功能。

decorated_function = logger(some_function)

Python 为此提供了更 Pythonic 的语法,它使用@符号。

@logger 
def  some_function ( text ): 
    print (text) 

some_function( "first test" ) 
# ----- some_function: start ----- 
# first test 
# ----- some_function: end -----

 some_function( "second test" ) 
# ----- some_function: start ----- 
# second test 
# ----- some_function: end -----

2 — @wraps 🎁

装饰器将包装器函数更新为看起来像原始函数并继承它的名称和属性。

为了理解它的@wraps作用以及为什么要使用它,让我们把前面的装饰器应用到一个简单的函数中,该函数将两个数字相加。

装饰器还没有使用@wraps

def logger(function):
    def wrapper(*args, **kwargs):
        """wrapper documentation"""
        print(f"----- {function.__name__}: start -----")
        output = function(*args, **kwargs)
        print(f"----- {function.__name__}: end -----")
        return output
    return wrapper

@logger
def add_two_numbers(a, b):
    """this function adds two numbers"""
    return a + b

add_two_numbers如果我们通过调用__name__和属性来检查修饰函数的名称和文档__doc__,我们会得到……不自然(但仍是预期的)结果:

add_two_numbers.__name__'包装器'

add_two_numbers.__doc__'包装器文档' 我们取而代之的是包装器名称和文档 ⚠️

这是不希望的结果。我们希望保留原始函数的名称和文档。这时候@wraps装饰器 就派上用场了。

您所要做的就是装饰包装函数。

from functools import wraps

def logger(function):
    @wraps(function)
    def wrapper(*args, **
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值