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

Python装饰器的定义及使用技巧和实例

发布时间:2023-10-26 17:15:04

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函数式编程的重要特性,可以通过它来简化原函数的代码、增加额外的功能,并有效地组织和管理代码。