• 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访问不太容易。。。)

  • 相关阅读:
    MongoDB学习笔记(五) MongoDB文件存取操作(转)
    MongoDB学习笔记(四) 用MongoDB的文档结构描述数据关系(转)
    Log4net配置相关
    UML 依赖 关联 聚合 组合
    亲属称谓
    Unity预定义程序集及自定义包编译顺序
    For Windows Phone8 phones make sure that the Windows Phone IP Over USB Transport(IpOverUsbSvc) service is running
    提升Entityframework效率的几种方法
    将RDLC报表工具栏中的英文改为中文
    C#函数式程序设计初探——基础理论篇
  • 原文地址:https://www.cnblogs.com/LuoboLiam/p/15071447.html
Copyright © 2020-2023  润新知