欢迎访问宙启技术站
智能推送

Python装饰器函数-在不修改原函数的前提下给函数添加功能

发布时间:2023-06-22 08:33:19

Python装饰器是一种特殊的函数,它可以在不修改原函数的前提下给函数添加功能,比如给函数增添日志记录、缓存、权限验证、性能检测等功能。使用装饰器能够提高代码复用性、可读性和可维护性。本文将通过简述装饰器的使用场景、定义和使用方式、装饰器函数的多重嵌套和参数传递来进行阐述。

一、使用场景

在实际开发中,经常需要对原函数进行扩展或修改。然而,在修改原函数的代码时,可能会出现风险,甚至导致原函数的不稳定或不可用。这时候,我们可以使用装饰器来实现在不改变原函数的前提下,给函数添加新的功能。通常,一些常见的使用场景包括:

1. 日志记录

在函数执行时记录日志,以便快速排查错误和异常。

2. 缓存

减少函数的执行时间,提高程序的性能。如果函数的输入相同,那么输出也相同,直接读取缓存结果即可。

3. 权限验证

验证用户或客户端的身份和权限,确保安全性。

4. 性能检测

记录函数的执行时间和资源消耗,分析函数的性能瓶颈,做出优化和调整。

二、定义和使用方式

装饰器函数是一个外部函数,它接收原函数作为参数,在内部定义一个新函数,并返回这个新函数。这个新函数包含有额外的功能,同时又保留原函数的功能不变。装饰器的语法格式是用一个@符号加上装饰器函数的名称来修饰原函数。

@decorator
def func():
    pass

例如:

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print('Function called: {}'.format(func.__name__))
        return func(*args, **kwargs)
    return wrapper

@log_decorator
def add(x, y):
    return x + y

result = add(3,4)
print('Result:', result)

结果为:

Function called: add
Result: 7

解释一下@log_decorator语句在Python中的作用:Python首先会找到log_decorator函数,并将下面的add函数作为参数传入。然后,log_decorator函数执行了一些额外的逻辑,并返回一个新的函数wrapper()。Python将wrapper()函数绑定到add函数名上,从此之后,每次调用add(x,y)函数都会首先调用wrapper()函数里面的打印语句,然后再继续执行原函数的逻辑。

三、装饰器多重嵌套

装饰器支持多个装饰器的嵌套,即一个装饰器函数可以和多个其他的装饰器函数一起使用。为此,我们可以用多个装饰器函数对原函数进行修饰。 Python处理这些装饰器的方式是:先运行最外层装饰器函数,然后再运行内层装饰器函数。

例如:

def log(msg):
    def decorate(func):
        def wrapper(*args, **kwargs):
            print("{0}".format(msg))  
            return func(*args, **kwargs) 
        return wrapper
    return decorate

@log('execute function add')
@log('This is the second log')
def add(x, y):
    return x + y

print(add(2,3))

结果为:

execute function add
This is the second log
5

四、装饰器参数传递

一种常见的问答题是:如何在装饰器代码中传递参数?对于这个问题,我们需要使用带参数的装饰器,装饰器内部定义一个函数,可以传递参数并返回一个裹住函数的包装器,包装起来的函数实现了其原有的功能,并附带上了新的加强功能。

实例如下:

def make_logger(log_level):
    def log_decorator(func):
        def wrapper(*args, **kwargs):
            if log_level == 'info':
                print("[INFO] Function executed:", func.__name__)
            elif log_level == 'debug':
                print("[DEBUG] Function executed:", func.__name__)
            return func(*args, **kwargs)
        return wrapper
    return log_decorator

@make_logger(log_level='debug')
def add(x, y):
    return x + y

print(add(2, 3))

结果为:

[DEBUG] Function executed: add
5

在上述示例中,定义了带参数的装饰器,即make_logger()。在使用装饰器修饰函数时,需要指定装饰器的参数,比如“log_level='debug'”。这样,在调用装饰器时,装饰器内部使用传递进来的参数,并返回一个带有参数的装饰器log_decorator(),这个log_decorator()函数和上面示例中的函数相同。最后,使用@make_logger装饰器时,需要为其传递参数,即log_level='debug'。

总结:

通过本文的介绍,我们了解了Python装饰器的用途、定义和应用场景。在实际开发中,装饰器提供了一种有效快速地扩展或修改现有函数功能的方法。它提高了代码复用性、可读性和可维护性,并使代码更加灵活和动态。同时,我们还掌握了多重嵌套的技巧和参数传递的方法。在以后的学习中,我们可以自己设计或使用已有的装饰器函数来增强函数的功能,提高程序开发效率。