函数06装饰器的应用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数06装饰器的应用相关的知识,希望对你有一定的参考价值。
1、写一个装饰器,实现缓存功能,允许过期,但没有换出,没有清除
1)cache的必要元素:key --> value
这里的key是函数的参数,value是函数的返回值
2)超时时间
超时时间如何存储
步骤1:
In [28]: from functools import wraps In [29]: def cache(fn): ...: cache_dict = {} ...: @wraps ...: def wraps(*args, **kwargs): ...: # 如何拼装key ...: if key in cache_dict.keys(): ...: # 如何实现超时检测 ...: return cache_dict[key] ...: result = fn(*args, **kwargs) ...: cache_dict[key] = result ...: return result ...: reutrn wraps
如何拼装key?
参数名 + 参数值
这里需要用到inspect库
标准库inspect的用法:
In [1]: import inspect In [2]: def add(x, y): ...: return x + Y ...: In [3]: inspect.signature Out[3]: <function inspect.signature> In [4]: inspect.signature(add) Out[4]: <Signature (x, y)> In [5]: sig = inspect.signature(add) # 获取到函数的签名 In [17]: sig.parameters Out[17]: mappingproxy({‘x‘: <Parameter "x">, ‘y‘: <Parameter "y">}) In [18]: for k in sig.parameters.keys(): # 获取参数 ...: print(k) ...: x y
步骤2:
In [30]: from functools import wraps In [31]: import inspect In [32]: def cache(fn): ...: cache_dict = {} ...: @wraps ...: def wraps(*args, **kwargs): ...: key = [] ...: params = inspect.Signature(fn).parameters ...: for i, arg in enumerate(args): ...: # 位置参数的名(行参x或y)和其值(实参) ...: name = list(params.keys())[i] ...: key.append((name, arg)) ...: key.extends(kwargs.items()) ...: # 拼接KEY ...: key.sort(key=lambda x: x[0] ...: key = ‘&‘.join([‘{}={}‘.format(name, arg) for name, arg in key]) ...: ...: if key in cache_dict.keys(): ...: # 如何实现超时检测 ...: return cache_dict[key] ...: result = fn(*args, **kwargs) ...: cache_dict[key] = result ...: return result ...: reutrn wraps
当被装饰的函数有默认参数时,造成key不一样,不走cache,怎么处理?
步骤3:
2、写一个装饰器,实现命令分发器,用户输入指令,执行相应的函数
以上是关于函数06装饰器的应用的主要内容,如果未能解决你的问题,请参考以下文章