Python中函数的装饰器(Decorator)的使用方法和应用场景
发布时间:2023-09-17 20:04:44
装饰器是Python中一种强大的特性,它能够在不修改被装饰函数源码的情况下,动态地添加功能。本文将介绍Python中函数的装饰器的使用方法和应用场景。
一、装饰器的使用方法
1. 定义装饰器
装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。通常情况下,装饰器会使用闭包来实现。
以下是一个示例装饰器的定义:
def decorator(func):
def wrapper(*args, **kwargs):
# 添加装饰功能
return func(*args, **kwargs)
return wrapper
2. 使用装饰器
使用装饰器时,需要在被装饰函数的定义之前加上装饰器的语法糖@,后面紧跟着装饰器函数的名称。
以下是一个示例被装饰函数的定义和装饰器的使用:
@decorator
def func():
pass
二、装饰器的应用场景
1. 计时器
装饰器可以用于计算函数的执行时间,可以在函数执行之前和之后记录时间,然后计算时间差。这在调优代码性能时非常有用。
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print('函数 {} 的执行时间为:{} 秒'.format(func.__name__, end_time - start_time))
return result
return wrapper
@timer
def long_running_function():
time.sleep(2)
long_running_function()
2. 权限验证
装饰器可以用于对需要进行权限验证的函数进行包装,以确保只有具有相应权限的用户才能执行该函数。
def login_required(func):
def wrapper(*args, **kwargs):
if user.is_authenticated:
return func(*args, **kwargs)
else:
raise Exception('请先登录')
return wrapper
@login_required
def access_sensitive_info():
pass
3. 日志记录
装饰器可以用于记录函数的调用日志,包括函数名称、参数和返回结果。这在程序调试和错误追踪时非常有用。
def logger(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
print('函数 {} 被调用,参数为:{},结果为:{}'.format(func.__name__, args, result))
return result
return wrapper
@logger
def add(x, y):
return x + y
add(1, 2)
4. 缓存
装饰器可以用于缓存函数的返回结果,以避免重复执行耗时的计算过程,提高代码的执行效率。
def cache(func):
cache = {}
def wrapper(*args, **kwargs):
key = str(args) + str(kwargs)
if key in cache:
return cache[key]
else:
result = func(*args, **kwargs)
cache[key] = result
return result
return wrapper
@cache
def fib(n):
if n <= 1:
return n
else:
return fib(n-1) + fib(n-2)
fib(10)
5. 日志处理
装饰器可以用于处理函数的异常,捕获异常并记录到日志中,使得代码更加健壮和容错。
import logging
def exception_handler(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
logging.error('函数 {} 抛出异常:{}'.format(func.__name__, str(e)))
return wrapper
@exception_handler
def divide(a, b):
return a / b
divide(10, 0)
在实际应用中,还有很多其他的场景可以使用装饰器,比如输入参数验证、函数重试、缓存失效策略等等。通过使用装饰器,可以更加灵活和高效地改进现有的函数功能,代码可读性也会大大提高。
