I´m trying to come up with a dynamic function calling system. I have a database with a bunch of differents levels: Decision Evaluator > Function (response curve) parameters > Inputs. Choosing a Decision Evaluator may call 10 different functions but only 5 inputs, treated differently through the parameters. So it would be way easier to have a dynamic system rather than create all the sub-calls for each main level.
In the test below, I can dynamically call a lower-level function from an upper level ('test'). When I try to pass arguments, I get the error 'str' object is not callable. Here's the trace:
C:\ProgramData\Anaconda3\lib\site-packages\openpyxl\worksheet\_reader.py:312: UserWarning: Data Validation extension is not supported and will be removed
warn(msg)
Traceback (most recent call last):
File "C:\Users\*\considerations.py", line 28, in <module>
ich.dynamic_call(abcd_3(show_test))
TypeError: 'str' object is not callable
init ICH...
oouh weee look at me
Process finished with exit code 1
considerations.py:
from input_clearing_house import InputClearingHouse
import pandas as pd
inputs = pd.read_excel(r'AXIS_DB.xlsx', sheet_name='Inputs')
considerations = pd.read_excel(r'AXIS_DB.xlsx', sheet_name='Considerations')
decision_score_evaluator = pd.read_excel(r'AXIS_DB.xlsx', sheet_name='DecisionScoreEvaluator')
decision_maker = pd.read_excel(r'AXIS_DB.xlsx', sheet_name='DecisionMaker')
considerations = pd.merge(considerations, inputs, on='input_name')
# print(considerations)
ich = InputClearingHouse()
abcd_2 = 'test'
abcd_3 = 'multi21'
show_test = 'dynamite'
ich.dynamic_call(abcd_2)
ich.dynamic_call(abcd_3(show_test))
input_clearing_house.py:
import math
class InputClearingHouse:
def __init__(self):
print('init ICH...')
def dynamic_call(self, name, *args, **kwargs):
call_fct = f'{name}'
if hasattr(self, call_fct) and callable(func := getattr(self, call_fct)):
func(*args, **kwargs)
def test(self):
print("oouh weee look at me")
def multi21(self, *args):
for arg in args:
print(arg)
def distance_to_target(self, source: tuple, target: tuple) -> float:
return math.sqrt((source[0] - target[0]) ** 2 (source[1] - target[1]) ** 2)
def my_endurance(self, current: int, maximum: int) -> float:
return current / maximum
CodePudding user response:
abcd_3(show_test)
is trying to use abcd_3
as a function, but it's a string that names a function.
ich.dynamic_call()
expects the name and arguments of the function to call to be separate arguments, so you should use
ich.dynamic_call(abcd_3, show_test)
CodePudding user response:
Your dynamic_call()
method already copes with variable numbers of arguments.
I think you just meant to add arguments:
ich.dynamic_call(abcd_3, show_test)