实现一个命令分发器

要求:

  程序员可以方便的注册函数到某个命令,用户输入命令时,路由到注册的函数,如果没有此命令,执行默认函数,用户输入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)
为什么要坚持,想一想当初!
原文地址:https://www.cnblogs.com/JerryZao/p/9574963.html