装饰器的应用题:命令分发器,缓存

写一个命令分发器

# def command_dispatcher():
#     cmd_table = {}      #构造一个全局字典
#
#     def reg(cmd):           # 写注册函数
#         def _reg(fn):
#             cmd_table[cmd] = fn
#             return fn
#         return _reg
#
#     def defult_func():         #写缺省函数
#         print("Unknown command")
#
#     def dispatcher():       #写分发器 调度
#         while True:
#             cmd = input('>>>')
#
#             if cmd.strip() == '':       # 退出条件
#                 return
#             cmd_table.get(cmd, defult_func)()
#     return reg, dispatcher
#
# reg, dispatcher = command_dispatcher()
#
# @reg('py')      # 自定义函数
# def foo1():
#     print('python')
#
# @reg('mag')
# def foo2():
#     print('magedu')
#
# dispatcher()    # 循环输入命令

实现命令分发器 优化 进阶

def commmand_dispatcher():
    commands = {}
    def reg(cmd,*args,**kwargs):        # 注册函数
        def _reg(fn):
            commands[cmd] = fn
            return fn
        return _reg

    def defaultfunc(*args,**kwargs):    # 没找到函数 执行
        print('Unknow Command')

    def dispatcher():
        while True:
            cmd = input('>>>>').strip()     # 输入的函数名 参数去除空格
            if cmd == '':       # 输入为空则退出函数
                return
            else:
                cmd,*params = cmd.split(maxsplit=1)     #将输入的函数按照空格切一刀 再解构
                args = []           # 空列表
                kwargs = {}            #空字典
                if params:          #判断patams是否是 空 0
                    for x in params[0].replace(',',' ').split():    # 将切出来的params遍历它的值v把逗号替换成空格再切一刀
                        tmp = x.split('=', maxsplit=1)          # 拿出x按照空格切一刀 看用户传参是否是关键字传参
                        if len(tmp) == 1:               #如果切出来的元素只有一个 说明是位置传参
                            args.append(tmp[0])         # 存进 args列表里面
                        elif len(tmp) == 2:             # 如果是两个就说明是关键字传参
                            kwargs[tmp[0]] = tmp[1]     #存进 kwargs字典里面

                    try:                            #异常处理
                        commands.get(cmd, defaultfunc)(*args, **kwargs)    
                    except Exception as e:
                        print(e,'异常处理结果,缺少参数')

    return  reg, dispatcher         # 返回reg,跟 dispatcher函数
######################################################
reg, dispatcher = commmand_dispatcher()

@reg('mag',100,y=200)           # 多参装饰器 默认值
def foo1(x, y):
    print('maged', x, y)
@reg('py',1000)
def foo2(a, b):
    print('python',a, b)
dispatcher()

实现一个cache(缓存)装饰器,实现过期被清楚功能

from functools import wraps
import inspect
import datetime
import time

def logger(fn):
    @wraps(fn)  #参数copy
    def wrapper(*args, **kwargss):
        start = datetime.datetime.now()
        ret = fn(*args, **kwargss)
        delta = (datetime.datetime.now() - start).total_seconds()
        print(fn.__name__,delta)
    return wrapper

def mag_cache(duration):
    def _cache(fn):
        local_cache = {}  #对不同函数名是不同的cache(缓存)
        @wraps(fn)      #参数copy
        def wrapper(*args, **kwargs):
            def clear_expire(cache):
                # 使用缓存时才清除过期的key,每一次调用先执行这一步把过期的清除
                expir_keys = []
                for k, (_, stamp) in local_cache.items():
                    now = datetime.datetime.now().timestamp()
                    if now - stamp > duration:
                        expir_keys.append(k)
                for k in expir_keys:
                    local_cache.pop(k)
            clear_expire(local_cache)

            def make_key():
                # 参数处理 构建key
                sig = inspect.signature(fn)
                params = sig.parameters     # 这里是只读了有序字典
                param_names = [key for key in params.keys()]      #list(params.keys)
                param_dict = {}     #目标参数字典

                param_dict.update(zip(params.keys(), args)) #有序的参数

                param_dict.update(kwargs)#关键字参数

                #缺省值处理
                for k in (params.keys() - param_dict.keys()):
                    param_dict[k] = params[k].default

                return tuple(sorted(param_dict.items()))
            key = make_key()


            #待补充,增加判断是否需要缓存
            if key not in local_cache.keys():
                local_cache[key] = (fn(*args, *kwargs),datetime.datetime.now().timestamp())     #时间戳

            return key, local_cache[key]
        return wrapper
    return _cache
@logger
@mag_cache(10)
def add(x,z,y=6):
    time.sleep(3)
    return x + y + z
result = []
result.append(add(4,5))
result.append(add(4,z=5))
result.append(add(4,y=6,z=5))
result.append(add(y=6,z=5,x=4))
result.append(add(4, 5, 6))
result.append(add(4,6))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值