Search code examples
pythonpython-3.xfunctools

Custom singledispatch like decorator for delegation


Is there any already available utility in python that can do what i am after?

Lets say I have a code like this,

import config


def process_data(arg):
    if config.processor == 'x':
        return process_data_x(arg)

    if config.processor == 'y':
        return process_data_y(arg)

    raise NotImplementedError() 

I want to express it as something like this

@singledispatch_on_config(config.processor)  # or may be take a func
def process_data(arg):
    raise NotImplementedError()


@process_data.when('x')
def process_x(args):
    pass

@process_data.when('y')
def process_y(args):
    pass

Any existing code snipet on how I can write them if nothing exists?


Solution

  • This is what I have come up so far,

    class Dispatcher:
        def __init__(self, valgen, def_func):
            self.registry = {}
            self.valgen = valgen
            self.def_func = def_func
    
        def when(self, value):
            def dec(func):
                self.registry[value] = func
                return self
            return dec
    
        def __call__(self, *args, **kwargs):
            val = self.valgen()
            impl = self.registry.get(val, self.def_func)
            return impl(*args, **kwargs)
    
    
    def cond_based_dispatcher(condition):
        def dec(func):
            return Dispatcher(condition, func)
        return dec
    
    
    key_func = lambda: 3
    
    
    @cond_based_dispatcher(key_func)
    def example():
        print('example')
    
    
    @example.when(1)
    def example_1():
        print('example 1')
    
    
    @example.when(2)
    def example_2():
        print('example 2')
    

    It "works", but if there is any other better approach for the problem in hand, i would gladly change it.