Sam Daniel
Sam Daniel

Reputation: 1902

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?

Upvotes: 1

Views: 67

Answers (1)

Sam Daniel
Sam Daniel

Reputation: 1902

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.

Upvotes: 1

Related Questions