• python singledispatch


    关于singledispatch的知识不赘述,直接百度即可。

    而singledispatch仅支持静态方法的dispatch,如果在class内部的方法则不行,因为第一个参数一直是self。

    所以下面是一个实现class内部singledispatch的方法。

    ### 基础的singledispatch装饰器只能实现静态方法
    from functools import singledispatch
    
    
    class TestClass(object):
        @singledispatch
        def test_method(arg, verbose=False):
            if verbose:
                print("Let me just say,", end=" ")
    
            print(arg)
    
        @test_method.register(int)
        def _(arg):
            print("Strength in numbers, eh?", end=" ")
            print(arg)
    
        @test_method.register(list)
        def _(arg):
            print("Enumerate this:")
    
            for i, elem in enumerate(arg):
                print(i, elem)
    
    if __name__ == '__main__':
        TestClass.test_method(55555)
        TestClass.test_method([33, 22, 11])
    
    -------------------
    ### singledispatch装饰器只能实现静态方法,因为装饰器返回的第一个参数在类中总是self
    # def wrapper(*args, **kw):
    #        return dispatch(args[0].__class__)(*args, **kw)
        
    # 第一种方法
    from functools import singledispatch, update_wrapper
    
    def methdispatch(func):
        dispatcher = singledispatch(func)
        def wrapper(*args, **kw):
            return dispatcher.dispatch(args[1].__class__)(*args, **kw)
        wrapper.register = dispatcher.register
        update_wrapper(wrapper, func)
        return wrapper
      
    class Patchwork(object):
    
        def __init__(self, **kwargs):
            for k, v in kwargs.items():
                setattr(self, k, v)
    
        @methdispatch
        def get(self, arg):
            return getattr(self, arg, None)
    
        @get.register(list)
        def _(self, arg):
            return [self.get(x) for x in arg]
    
          
    # 第二种方法
    from functools import singledispatch
    
    class TestClass(object):
    
        def __init__(self):
          
            self.test_method = singledispatch(self.test_method)
            self.test_method.register(int, self._test_method_int)
            self.test_method.register(list, self._test_method_list)
    
        def test_method(self, arg, verbose=False):
            if verbose:
                print("Let me just say,", end=" ")
    
            print(arg)
    
        def _test_method_int(self, arg):
            print("Strength in numbers, eh?", end=" ")
            print(arg)
    
        def _test_method_list(self, arg):
            print("Enumerate this:")
    
            for i, elem in enumerate(arg):
                print(i, elem)
    
    
    if __name__ == '__main__':
        test = TestClass()
        test.test_method(55555)
        test.test_method([33, 22, 11])
    

    重点关注这里即可:

    def methdispatch(func):
        dispatcher = singledispatch(func)
        def wrapper(*args, **kw):
            return dispatcher.dispatch(args[1].__class__)(*args, **kw)
        wrapper.register = dispatcher.register
        update_wrapper(wrapper, func)
        return wrapper
    

    这个装饰器的实际作用是把dispatch的原则调整为按照args[1]的type来dispatch。

    以上代码来自于:参考资料
    (粘过来的原因是github访问不太容易。。。)

  • 相关阅读:
    Flask快速入门(14) — 请求上下文2
    Flask快速入门(13) — 请求上下文1
    24 python异常机制
    11 python socket网络编程
    21 python调用外部系统命令
    10 python从键盘获取输入、刷新缓冲区
    18 python文件、目录操作
    17 python内置特殊方法
    15 python之ORM sqlalchemy模块使用
    14 python类的继承
  • 原文地址:https://www.cnblogs.com/LuoboLiam/p/15071447.html
Copyright © 2020-2023  润新知