022_Python装饰器_案例_Fib数列缓存

在推导Fib数列过程中利用Python装饰器的实现缓存,解决利用递归实现Fib数列的过程中,出现的大量重复计算,进而影响性能的问题
ps:不借助Python中自带的解决缓存问题的解释器
from functools import lru_cache

from functools import wraps
import time
# 官方自带的缓存装饰器,可结合场景使用
# from functools import lru_cache


def timeit(func):  
    """打印被装饰函数运行总时间的装饰器"""

    # @wraps保留被装饰函数的函数名和帮助文档, 否则是wrapper的信息.
    @wraps(func)
    def wrapper(*args, **kwargs): 
        start_time = time.time()
        result = func(*args, **kwargs)  
        end_time = time.time()
        print("%s函数运行总时间为%fs" % (func.__name__, end_time - start_time))
        return result 

    return wrapper  


def fib_cache(func):
    """对被装饰函数(fib数列生成器)的推导结果进行缓存的装饰器"""
    caches = {1: 1, 2: 1, 3: 2, 4: 3, 5: 5}

    # @wraps保留被装饰函数的函数名和帮助文档, 否则会是wrapper的信息.
    @wraps(func)
    def wrapper(num):
        # 如果缓存中能找到第num个Fib数列的值, 直接返回。
        if num in caches:
            return  caches.get(num)
        #  如果缓存中不能找到第num个Fib数列的值,
        #       1). 先执行函数func(num)计算结果。
        #       2). 然后将将计算的结果存储在缓存中。并返回计算结果
        else:
            result = func(num)
            caches[num] = result
            return result

    return wrapper


@fib_cache  # fib1 = fib_cache(fib1)
def fib1(num):
    """计算Fib数列的第num 个值"""
    if num in (1, 2):
        return 1
    else:
        return fib1(num - 1) + fib1(num - 2)


def fib2(num):
    """计算Fib数列的第num 个值"""
    if num in (1, 2):
        return 1
    else:
        return fib2(num - 1) + fib2(num - 2)


# 利用定义的性能装饰器对使用缓存的fib生成器的运行时间进行检测
@timeit # use_cache = timeit(use_cache)
def use_cache():
    result = fib1(20)
    print(result)


# 利用定义的性能装饰器对未使用缓存的fib生成器的运行时间进行检测
@timeit
def no_cache():
    result = fib2(20)
    print(result)


if __name__ == '__main__':
    use_cache()
    no_cache()

执行结果:
在这里插入图片描述

发布了37 篇原创文章 · 获赞 0 · 访问量 5318

猜你喜欢

转载自blog.csdn.net/qq_21156327/article/details/103686619
今日推荐