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

Python装饰器:如何加强或修改函数的功能?

发布时间:2023-06-19 14:31:12

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),从而提高代码的复用性和可维护性。