Skip to content

Latest commit

 

History

History
204 lines (138 loc) · 3.58 KB

307_装饰器应用.md

File metadata and controls

204 lines (138 loc) · 3.58 KB

装饰器的应用

命令分发器

程序员可以轻松的注册一个函数到某一个命令,用户输入命令时,路由到注册的函数, 如果此命令没有对应的注册函数,执行默认的函数

分析

  • 输入命令映射到函数对象,并执行这个函数,应该是cmd_tb[cmd]=fn,字典正好合适
  • 如果输入一个cmd命令后,没有找到函数,就要调用缺省的函数执行,这正好是字典的缺省值参数
  • cmd是字符串
  • 接受用户的传入就可以使用input函数

基础框架

commands = {}


def reg(name):
    def wrapper(func):
        commands[name] = func
        return func
    return wrapper


def default_func():
    print('Unknown command')


def dispatcher():
    while True:
        cmd = input('>>>')
        if cmd.strip() == "":
            continue
        if cmd in ('exit', 'EXIT', 'q', 'Q'):
            break
        commands.get(cmd, default_func)()


@reg('foo1')
def foo1():
    print('foo1')


@reg('foo2')
def foo2():
    print('foo2')


dispatcher()

封装

commands = {}


def reg(name):
    def wrapper(func):
        commands[name] = func
        return func
    return wrapper


def default_func():
    print('Unknown command')


def dispatcher():
    while True:
        cmd = input('>>>')
        if cmd.strip() == "":
            continue
        if cmd in ('exit', 'EXIT', 'q', 'Q'):
            break
        commands.get(cmd, default_func)()


@reg('foo1')
def foo1():
    print('foo1')


@reg('foo2')
def foo2():
    print('foo2')


dispatcher()

进阶

要实现下面的功能 @reg(f1, x=200, y = 300)

方法一

def command_dispatcher():
    command = {}

    def reg(name, *args, **kwargs):
        def wrapper(fn):
            command[name] = fn, args, kwargs
            return fn
        return wrapper

    def default_func():
        print("UNKNOWN COMMAND!")

    def dispatcher():
        while True:
            cmd = input('>>>')
            if cmd.strip() == '':
                break
            fn, args, kwargs = command.get(cmd, (default_func, (), {}))
            fn(*args, **kwargs)
    return reg, dispatcher


reg, dispatcher = command_dispatcher()

@reg('f1', 200, 300)
@reg('f2', 300, 400)
def foo1(x, y):
    print('foo1',x+y)

@reg('f4')
def foo2():
    print('foo2')

dispatcher()

方法二

实现下面的功能

>>> f2 100 200
foo2 300
def command_dispatcher():
    command = {}

    def reg(name):
        def wrapper(fn):
            command[name] = fn
            return fn
        return wrapper

    def default_func(*args, **kwargs):
        print("UNKNOWN COMMAND!")

    def dispatcher():
        while True:
            cmd = input('>>>')
            if cmd.strip() == '':
                break
            args, kwargs = [], {}
            func_name, *params = cmd.replace(",", ' ').split()
            for param in params:
                x = param.split('=', maxsplit=1)
                if len(x) == 1:
                    args.append(int(x[0]))
                if len(x) == 2:
                    kwargs[x[0]] = int(x[1])
            command.get(func_name, default_func)(*args,**kwargs)
    return reg, dispatcher


reg, dispatcher = command_dispatcher()

@reg('f1')
def foo1(x, y):
    print('foo1',x+y)

dispatcher()