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:
- You left out
self
from yourput_in_db
method. - 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.