Python装饰器:如何加强或修改函数的功能?
Python装饰器是一种很有用的编程技术,它可以在不修改函数源代码的情况下,增强或修改函数的功能。装饰器是一种函数或者一个类,它可以接收一个函数作为参数,并且在函数执行前或执行后,进行一些额外的操作。下面我们将从以下方面介绍Python装饰器的使用:
1. 为函数加上计时器
我们经常需要知道函数的运行时间,以便对程序进行优化。这时我们可以使用装饰器来为函数加上计时器:
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print("函数 %s 运行时间为:%.2f秒" % (func.__name__, end_time-start_time))
return result
return wrapper
@timer
def my_function():
# do something
pass
上面的代码中,timer是一个装饰器函数,它接收一个函数作为参数,并返回一个新的函数wrapper。wrapper函数接收任意数量的位置参数和关键字参数,然后记录函数开始和结束时间,并打印出时间差,最后返回函数的结果。
2. 为函数加上日志
我们可以使用装饰器来为函数添加日志功能:
def logger(func):
def wrapper(*args, **kwargs):
print("函数 %s 被调用" % func.__name__)
result = func(*args, **kwargs)
print("函数 %s 执行完成" % func.__name__)
return result
return wrapper
@logger
def my_function():
# do something
pass
上面的代码中,logger是一个装饰器函数,它接收一个函数作为参数,并返回一个新的函数wrapper。wrapper函数在函数执行前打印出“函数被调用”的日志,在函数执行后打印出“函数执行完成”的日志,并返回函数的结果。
3. 为函数加上缓存
我们可以使用装饰器来为函数添加缓存功能,以便重复调用的时候可以从缓存中获取结果,而不需要重新计算:
def cache(func):
results = {}
def wrapper(*args):
if args in results:
print("从缓存中获取结果")
return results[args]
else:
result = func(*args)
results[args] = result
return result
return wrapper
@cache
def my_function(n):
# do something
return result
上面的代码中,cache是一个装饰器函数,它接收一个函数作为参数,并返回一个新的函数wrapper。wrapper函数接收一个参数n,如果结果已经计算过,就从缓存中获取结果并打印出“从缓存中获取结果”的信息,否则计算结果并把结果存入缓存中。
4. 为函数添加权限控制
我们可以使用装饰器为函数添加权限控制的功能,比如限制只有管理员才能执行:
def admin_required(func):
def wrapper(*args, **kwargs):
if not current_user.is_admin:
raise Exception("只有管理员才能执行该操作")
return func(*args, **kwargs)
return wrapper
@admin_required
def delete_user():
# do something
pass
上面的代码中,admin_required是一个装饰器函数,它接收一个函数作为参数,并返回一个新的函数wrapper。wrapper函数在执行前先判断当前用户是否为管理员,如果不是则抛出异常,否则执行原来的函数。
5. 为函数添加重试功能
有时候我们需要对某些操作进行多次重试,比如网络请求失败时,可以添加一个装饰器为函数添加重试功能:
def retry(times):
def decorated(func):
def wrapper(*args, **kwargs):
for i in range(times):
try:
result = func(*args, **kwargs)
return result
except Exception as e:
print("第 %d 次重试失败,原因:%s" % (i+1, str(e)))
print("所有重试失败")
return wrapper
return decorated
@retry(3)
def my_function():
# do something
pass
上面的代码中,retry是一个装饰器函数,它接收一个参数times,表示重试次数。它返回一个新的decorated函数,decorated函数接收一个函数作为参数,并返回一个新的函数wrapper。wrapper函数在执行时,会尝试执行原来的函数,如果出现异常则进行重试,如果重试超过指定次数,则打印出“所有重试失败”的信息。
总结:Python装饰器是一种非常实用的编程技术,它可以让我们在不改变函数源代码的情况下,为函数添加很多有用的功能。我们可以使用装饰器为函数添加计时器、日志、缓存、权限控制、重试等功能。在实际编程中,装饰器经常被用来进行面向切面设计(AOP),从而提高代码的复用性和可维护性。
