Я искал алгоритм, способный хранить и запускать функции с гибким числом аргументов. Я закончил тем, что нашел аналог переключателя / корпуса для python, который соответствует моим требованиям:
def opA_2(x, y):
return x - y
def opB_3(x, y, z):
return x + y - z
def opC_2(x, y):
return x * y
def opD_3(x, y, z):
return x * y + z
op_dict = {'opA_2': opA_2,
'opB_3': opB_3,
'opC_2': opC_2,
'opD_3': opD_3
}
op_lambda_dict = {'opA_2': lambda x, y, kwargs: op_dict['opA_2'](x, y),
'opB_3': lambda x, y, kwargs: op_dict['opB_3'](x, y, kwargs['z']),
'opC_2': lambda x, y, kwargs: op_dict['opC_2'](x, y),
'opD_3': lambda x, y, kwargs: op_dict['opD_3'](x, y, kwargs['z']),
}
def dispatch_op(func_dict, op, x, y, **kwargs):
return func_dict.get(op, lambda a, b, c: None)(x, y, kwargs)
coefs_dict = {'i': 1, 'j': 2, 'k': 3, 'z': 4}
print('Original lambda dict result:', dispatch_op(op_lambda_dict, 'opB_3', 1, 2, **coefs_dict))
Результат:
Original lambda dict result: -1
Как только я реализовал эту структуру к моему целевому коду, однако, я столкнулся со многими проблемами, потому что мои операции определены через al oop.
Насколько я понимаю, это потому, что лямбда-функции не инициализированы и в конечном итоге указывают на последнюю объявленную операцию.
Этот дополнительный код воспроизводит проблему:
op_looplambda_dict = {}
for label, func in op_dict.items():
if '2' in label:
op_looplambda_dict[label] = lambda x, y, kwargs: func(x, y)
if '3' in label:
op_looplambda_dict[label] = lambda x, y, kwargs: func(x, y, kwargs['z'])
print('Loop lambda dict result:', dispatch_op(op_looplambda_dict, 'opB_3', 1, 2, **coefs_dict))
Результат:
Loop lambda dict result: 6
Это результат opD_3
вместо opB_3
Интересно, может ли кто-нибудь дать какой-нибудь совет, как правильно объявить лямбда-функции во втором случае или другую структуру кода, чтобы этого избежать. Большое спасибо.