Home > Enterprise >  How can I invoke a functional_call using dictionary parameters passed to it?
How can I invoke a functional_call using dictionary parameters passed to it?

Time:11-11

My class Test below can have multiple functions, in this example, one of the functions is put_in_db(). My class expects a JSON object that will get converted to the dictionary and will be passed to invoke_func. Now, within invoke_func, how can I invoke different functions using the key functional_call and the parameters list using params. I have chosen params as a list so that the order is maintained. I cannot change put_in_db() function since this can be from an external class too.

class Test:
    def __init__(self):
        print("Test initialized")
        
    def put_in_db(name, age):
        print("put in db")
        
    def invoke_func(self, my_dict):
        print(my_dict)
        function_call = my_dict.get('functional_call')
        params = my_dict.get('params')
        print(params)
        '''
        how to invoke put_in_db from here using function_call 
        and params
        '''
        
if __name__ == "__main__":
    T = Test()
    data = {'functional_call': 'put_in_db', 'params': [{'name': 'Saf', 'age': '81'}]}
    T.invoke_func(data)

CodePudding user response:

You can use exec():

def invoke_func(self, my_dict):
    print(my_dict)
    function_call = my_dict.get('functional_call')
    params = my_dict.get('params')
    print(params)
    exec(f'{function_call}({params})')

Note: exec() does have security vulnerabilities, as it will execute any code that is passed to it, so exercise caution when the user inputs something that is then executed.

CodePudding user response:

class Test:
    def __init__(self):
        print("Test initialized")
        
    def put_in_db(self,name, age):
        print(f"put {name}, age {age}, in db")
        
    def invoke_func(self, my_dict):
        print(my_dict)
        function_call = my_dict.get('functional_call')
        params = my_dict.get('params')
        print(params)
        getattr(self,function_call)(**params)
        
if __name__ == "__main__":
    T = Test()
    data = {'functional_call': 'put_in_db', 'params': {'name': 'Saf', 'age': '81'}}
    T.invoke_func(data)

getattr(some_object, att_name) will grab the attribute att_name from some_object, assuming it exists (if not it will give an AttributeError unless you also include a default). Then you can just invoke it by unpacking params as an argument.

I made two other changes to your code:

  1. You left out self from your put_in_db method.
  2. You made param a list containing a dict, but it's easier to work with if you just make it a dict.

You will probably want to add some error checks error checks for if/when someone passes in an string that doesn't correspond to an attribute.

  • Related