zoukankan      html  css  js  c++  java
  • 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访问不太容易。。。)

  • 相关阅读:
    jQuery 基础一 样式篇
    javaJavaScript DOM
    linux 实用命令
    Linux下修改.bash_profile 文件改变PATH变量的值
    java 字符串截取的方法
    Telnet命令参考手册
    linux下dubbo调试 ---telnet命令
    【Spring Task】定时任务详解实例-@Scheduled
    Spring定时任务的几种实现
    SQL之case when then用法
  • 原文地址:https://www.cnblogs.com/LuoboLiam/p/15071447.html
Copyright © 2011-2022 走看看