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