Python装饰器的定义及使用技巧和实例
Python装饰器是一种特殊的函数,用于修改其他函数的功能。它是Python语言特有的一种语法,可以对已有的函数进行包装,为其添加额外的功能,而不修改原函数的代码。
定义装饰器的一般形式如下:
def decorator(func):
def wrapper(*args, **kwargs):
# 在被装饰函数前添加额外的功能
# 调用被装饰的函数并返回结果
return func(*args, **kwargs)
return wrapper
装饰器接受一个函数作为参数,并返回一个经过包装后的新函数。在新函数中,可以添加额外的功能,并调用原函数。装饰器使用内部函数(wrapper)返回,这样装饰器的调用不会立即执行,而是在被装饰函数 次被调用时执行。
使用装饰器的时候,可以使用@语法糖,将装饰器直接放在被装饰函数的定义之前。例如:
@decorator
def func():
pass
实际上,这行代码等同于func = decorator(func)。
装饰器有许多应用场景,下面给出一些使用技巧和实例。
1. 修改函数的输入和输出
装饰器可以修改函数的输入和输出,对输入进行验证和转换,对输出进行处理。例如,下面的装饰器用来计算函数的执行时间:
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print("Execution time:", end_time - start_time, "seconds")
return result
return wrapper
@timer
def myfunc():
time.sleep(1)
print("Function is executed")
当调用myfunc()时,装饰器会在函数执行前后打印出执行时间。通过装饰器,不需要修改原函数的代码,就可以添加额外的功能。
2. 缓存函数的结果
装饰器可以缓存函数的结果,避免重复计算。例如,下面的装饰器用来缓存斐波那契数列的计算结果:
def memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
当调用fibonacci(10)时,装饰器会先检查缓存中是否有之前的计算结果,若有则直接返回,否则计算并缓存结果。通过装饰器,可以有效提高计算效率。
3. 权限验证
装饰器可以用来限制函数的访问权限,只有满足一定条件的用户才能使用该函数。例如,下面的装饰器用来验证用户是否登录:
def login_required(func):
def wrapper(*args, **kwargs):
if not user.is_authenticated():
raise Exception("User is not logged in")
return func(*args, **kwargs)
return wrapper
@login_required
def myfunc():
pass
当调用myfunc()时,装饰器会检查用户是否登录,若未登录则抛出异常。通过装饰器,可以方便地加入权限验证逻辑。
4. 日志记录
装饰器可以用来记录函数的调用和返回信息,方便调试和分析。例如,下面的装饰器用来记录函数的调用和执行时间:
import logging
def log_execution(func):
logger = logging.getLogger("execution")
def wrapper(*args, **kwargs):
logger.info("Function %s is called with arguments %s and %s", func.__name__, args, kwargs)
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
logger.info("Function %s is executed in %s seconds, result is %s", func.__name__, end_time - start_time, result)
return result
return wrapper
@log_execution
def myfunc():
pass
当调用myfunc()时,装饰器会记录函数的调用和执行时间,并打印到日志中。通过装饰器,可以方便地添加日志记录功能。
以上是Python装饰器的定义及使用技巧和实例。装饰器是Python函数式编程的重要特性,可以通过它来简化原函数的代码、增加额外的功能,并有效地组织和管理代码。
