美文网首页Python全栈工程师
19.3-装饰器习题cache和命令分发器实现

19.3-装饰器习题cache和命令分发器实现

作者: BeautifulSoulpy | 来源:发表于2019-09-21 10:34 被阅读0次

    当你处于低潮期的时候,好好想想,就算现在攒不到钱,攒点知识,交情,经验,最不济攒点教训也行!

    装饰器一定要多加练习,装饰器是越练越熟练;后面很多框架一装饰就能用了,
    经常见到的各种类型的装饰器都要练一遍;

    本章总结:

    1. 无参、有参、缓存装饰器、通用装饰器、 1.40;
    2. 装饰器是AOP面向对象编程 Aspect Oriented Programming思想的体现
    3. 想装饰器 return 是什么 很重要,
    装饰器

    装饰器(Decorator)是python的一个重要部分,简单来说,他是修改其他函数功能的函数。

    它是一种不修改原来的业务代码,给程序动态添加功能的技术;例如logger函数功能就是对业务函数增加日志的,而业务函数中应该吧业务无关的日志玻璃干净;

    他们有助于让我们的代码更简短,也更Pythonic!

    解除装饰器:
    可以访问 _wrapped_属性来访问原始函数

    orig_add = add.__wrapped__
    orig_add(1,2)
    

    装饰器应用场景
    日志、监控、权限、设计、参数检查、路由等处理
    这些功能与业务功能无关,很多业务都需要的公有的功能,所以适合独立出来,对目标对象进行增强;

    1. 缓存装饰器实现;

    
    from functools import wraps
    import inspect,datetime
    
    def mag_cache(fn):
        local_cache = {}
        @wraps(fn)
        def wrapper(*args, **kwargs):
            # 参数处理,构建key
            sig = inspect.signature(fn)  
            params = sig.parameters
            
            params_dict = {}
            
            values = list(params.values())
            keys = list(params.keys())
            
            # 位置和关键字传参
            params_dict.update(zip(params.keys(),args))
            params_dict.update(kwargs)
            
            # 缺省值
            for k,v in params.items():
                if k not in params_dict:
                    params_dict[k] = v.default
                    
            key = tuple(sorted(params_dict.items()))
            print(key)
            
            if key not in local_cache.keys():
                local_cache[key] = fn(*args,**kwargs)
            
            return local_cache[key]
        return wrapper
    
    @mag_cache
    def add(x,y,z=6):
        datetime.sleep(2)
        return x+y+z
    
    
    2.命令分发器实现
    # 1 基本框架
    # 第一个版本:
    commands = {}
    
    def reg(cmd, fn):
        commands[cmd] = fn
    
    def defaultfn():
        print("Unknown command")
        
    def foo1():    # 硬编码
        print('magedu')
        
    def foo2():   # 硬编码
        print('python')
    reg('mag', foo1)
    reg('py', foo2)
        
    def dispatcher():
        while True:
            cmd = input('>>>').strip()
            if cmd == '':
                print('bye')
                return
            commands.get(cmd, defaultfn)()
    
    dispatcher()
    -------------------------------------
    >>>mag
    magedu
    >>>py
    python
    >>>
    bye
    
    
    # 2 柯里化变有参
    commands = {}
    
    def reg(cmd):
        def _reg(fn):
            commands[cmd] = fn
            return fn
        return _reg
    
    def defaultfn():
        print("Unknown command")
    
    @reg('mag')
    def foo1():
        print('magedu')
       
    @reg('py')
    def foo2():
        print('python')
    #reg('mag', foo1)
    #reg('py', foo2)
        
    def dispatcher():
        while True:
            cmd = input('>>>').strip()
            if cmd == '':
                print('bye')
                return
            commands.get(cmd, defaultfn)()
    
    dispatcher()
    -------------------------------------
    >>>mag
    magedu
    >>>py
    python
    >>>
    bye
    
    
    
    # 3 函数封装
    def cmds_dispatcher(defaultfn=lambda :print('Unknown command')):
        commands = {}
    
        def reg(cmd):
            def _reg(fn):
                commands[cmd] = fn
                return fn
            return _reg
    
        #def defaultfn():
        #    print("Unknown command")
    
        def dispatcher():
            while True:
                cmd = input('>>>').strip()
                if cmd == '':
                    print('bye')
                    return
                commands.get(cmd, defaultfn)()
                
        return reg,dispatcher
            
    reg, dispatcher = cmds_dispatcher()
            
    @reg('mag')
    def foo1():
        print('magedu')
       
    @reg('py')
    def foo2():
        print('python')
    #reg('mag', foo1)
    #reg('py', foo2)
    
    dispatcher()
    
    

    相关文章

      网友评论

        本文标题:19.3-装饰器习题cache和命令分发器实现

        本文链接:https://www.haomeiwen.com/subject/jrmductx.html