要求:
程序员可以方便的注册函数到某个命令,用户输入命令时,路由到注册的函数,如果没有此命令,执行默认函数,用户输入input
分析:
1 '''实现一个命令分发器''' 2 3 # 初步实现 4 commands = {} # 命令字典 5 6 def reg(cmd, fn): 7 commands[cmd] = fn 8 9 # 默认函数 10 def defaultfn(): 11 print('Unkonw cmd') 12 13 # 函数 14 def foo1(): 15 print('1') 16 17 def foo2(): 18 print('2') 19 20 # 注册(但是要有判断,不同用户或同一个用户,注册时使用的名字一样,会冲突,会覆盖 21 # 1、每个用户有自己的commands 22 # 2、加判断条件 23 reg('mag',foo1) 24 reg('py',foo2) 25 26 27 def dispatcher(): 28 while True: 29 cmd = input('>>') 30 if cmd == '': 31 print('bye') 32 break 33 commands.get(cmd, defaultfn)() # 拿到的是defaultfn对象,所以还要加一个括号 34 35 dispatcher() 36 print(commands) 37 38 # 输出: 39 # >>ds 40 # Unkonw cmd 41 # >>mag 42 # 1 43 # >>py 44 # 2 45 # >> 46 # bye 47 # {'mag': <function foo1 at 0x0000000001E5C620>, 'py': <function foo2 at 0x0000000001E5C6A8>} 48 49 50 # 添加装饰器:现在的顺序是由上至下 51 commands = {} # 命令字典 52 53 def reg(cmd): 54 def _reg(fn): 55 commands[cmd] = fn 56 return fn 57 return _reg 58 59 60 # # 默认函数 61 def defaultfn(): 62 print('Unkonw cmd') 63 64 # 函数 65 @reg('mag') # foo1 = reg('mag')(add) = _reg(add) 66 #从装饰器的定义出发,先程序由上到下,到此处时,先执行foo1=reg('mag')(foo1),创建foo1函数对象,此时已经注册好了 67 def foo1(): 68 print('1') 69 @reg('py') 70 def foo2(): 71 print('2') 72 73 74 def dispatcher(): 75 while True: 76 cmd = input('>>') 77 if cmd == '': 78 print('bye') 79 break 80 commands.get(cmd, defaultfn)() # 拿到的是defaultfn对象,所以还要加一个括号 81 print(commands) 82 dispatcher() 83 print(commands) 84 85 # 封装: 86 def cmds_dispatcher(): 87 commands = {} # 命令字典 88 89 def reg(cmd): 90 def _reg(fn): 91 commands[cmd] = fn 92 return fn 93 return _reg 94 95 96 # 默认函数 97 def defaultfn(): 98 print('Unkonw cmd') 99 100 def dispatcher(): 101 while True: 102 cmd = input('>>') 103 if cmd == '': 104 print('bye') 105 break 106 commands.get(cmd, defaultfn)() # 拿到的是defaultfn对象,所以还要加一个括号 107 print(commands) 108 return reg,dispatcher 109 110 reg,run = cmds_dispatcher() 111 112 # 函数 113 @reg('mag') # foo1 = reg('mag')(add) = _reg(add) 114 #从装饰器的定义出发,先程序由上到下,到此处时,先执行foo1=reg('mag')(foo1),创建foo1函数对象,此时已经注册好了 115 def foo1(): 116 print('1') 117 @reg('py') 118 def foo2(): 119 print('2') 120 121 run()
使用类封装实现命令分发器
########################### 命令分发器################################# # 简单实现 函数注册,并且传入参数 class Dispatcher: def __init__(self): pass def reg(self, cmd, fn): setattr(self, cmd, fn) def run(self, *args, **kwargs): while True: cmd = input('>>>').strip() if cmd == '': break else: getattr(self, cmd, lambda :print('unkonw'))(*args, **kwargs) def add(x, y): print(x + y) def sub(x, y): print(x - y) dis = Dispatcher() dis.reg('add', add) dis.reg('sub', sub) dis.run(4, y = 5) # # 实现函数注册,并且传入参数 class Dispatcher: def __init__(self): # self.commands = {} pass def reg(self, cmd):# 风险,万一人家实例本身有相同的属性名,这样就会冲突,覆盖,最好的方式是使用一个字典存 def wrapper(fn): setattr(self, cmd, fn) return fn return wrapper def run(self, *args, **kwargs): while True: cmd = input('>>>').strip() if cmd == '': break else: getattr(self, cmd, lambda :print('unkonw'))(*args, **kwargs) dis = Dispatcher() # 这样的话,加载的时候,函数已经被注册进去了,运行的时候,根据cmd直接调用 @dis.reg('add') # add = dis.reg('add')(add) def add(x, y): print(x + y) @dis.reg('sub') # add = dis.reg('add')(add) def sub(x, y): print(x - y) dis.run(4, y = 5)