写一个命令分发器
# 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))