Home > database >  Best practice to match callable function
Best practice to match callable function

Time:02-24

I'd like to have a set of functions which can be called upon specific input types. I provide a brief example, let's say I have the following description in a JSON

{
  "type": "location",
  "precision": 100
}

and I have 2 functions such as

fun1(type,param) # Here param is intended as the precision
fun2(type,param) # Here param is intended as another variable

however, I want to be able to match the description only with fun1 which has the correct type and param, although the python type of param can be the same for both function, however with a different meaning. Moreover, there can be multiple param to check.

Has python something handy to handle this?

CodePudding user response:

The easiest way is probably to use a dictionary for the mapping and (optional) associate every function with an appropriate attribute to keep track:

# untested

def func1(data, param):
    pass
    # do something

func1.type = "location"

def func2(data, param):
    pass
    # do something

func2.type = "something_else"

funcs = [func1, func2]

type_func_map = {func.type: func for func in funcs}


# apply the function to data:

def apply_matching_func(data, param):
    func = type_func_map.get(data["type"])
    if func:
        return func(data, param)

CodePudding user response:

Let's suppose, you have already loaded your functions to dict in Python.

There are many approaches, how to do the job, so I will write only few of them down here and demonstrate on only on few of them.

  1. Function decorators to verify, whether the dictionary contains the right variable before calling it. -- This approach is by my opinion best for short scripts.

  2. If else chain with your types -- I think, this approach is the best for long term maintenance.

  3. Check in the beginning of function whether you want to run it. -- If you don't care about anything and want a short code to run in shortest possible time.

  4. Map from type to correct function -- This approach is for good performance

Demonstration of first approach

First, we have to make a function generating decorators.

def dec_gen(the_type: str):

  def dec(func):
    def inner(d: dict):
      if d.get('type') == the_type:
        func(d)

    return inner

  return dec

Let's change fun1 a little bit.

@dec_gen('location')
def fun1(d: dict):
  ...your code....

Demonstration of third approach

Let's change fun1 a little bit (again)

def fun1(d: dict):
  if d.get('type') == 'location':
    ...your code...

If you write such header for all fun1, fun2,..., funn, you can just pass the dictionary and it will be run only on few of them.

Of course, this one can get terribly slow for many different types and large N, but there is no requirement on speed in your question.

Demonstration of forth approach

See the other answer.

  • Related