Передайте список функций с соответствующими параметрами другой функции

Я изо всех сил пытаюсь передать список функций со списком соответствующих параметров. Я также проверил здесь , но это было не очень полезно. например (наивный подход, который не работает):

def foo(data, functions_list, **kwarg): for func_i in functions_list: print func_i(data, **kwarg) def func_1(data, par_1): return some_function_1(data, par_1) def func_2(data, par_2_0, par_2_1): return some_function_2(data, par_2_0, par_2_1) foo(data, [func_1, func_2], par_1='some_par', par_2_0=5, par_2_1=11) 

Важно отметить , что par_1 нельзя использовать в func_2 , поэтому каждая функция потребляет уникальный набор параметров.

Вы можете использовать имя функции в качестве аргументов ключевого слова. При индексировании kwargs вы должны использовать func_i.__name__ в качестве ключа.

 def foo(data, function_list, **kwargs): for func_i in function_list: print(func_i(data, kwargs[func_i.__name__])) 

И сейчас,

 foo(data, [func_1, func_2], func_1='some_par', func_2=[5, 11]) 

Вы можете использовать inspect.getargspec (я предполагаю, что вы используете Python 2, вы не должны использовать эту функцию в Python 3, потому что она устарела), чтобы выяснить, какие имена аргументов имеют функция и построить новый словарь на основе этих:

 import inspect def foo(data, functions_list, **kwargs): for func_i in functions_list: newkwargs = {name: kwargs[name] for name in inspect.getargspec(func_i).args if name in kwargs} print(func_i(data, **newkwargs)) def func_1(data, par_1): return data, par_1 def func_2(data, par_2_0, par_2_1): return data, par_2_0, par_2_1 >>> data = 10 >>> foo(data, [func_1, func_2], par_1='some_par', par_2_0=5, par_2_1=11) (10, 'some_par') (10, 5, 11) 

Но лучшим способом было бы просто связать параметры с функциями, которые не полагаются на самоанализ.

Если вы хотите сохранить функцию foo с тем же самым объявлением, и вы не против каждой функции, получающей весь набор параметров, вы можете сделать это следующим образом:

Вам просто нужно добавить к каждой функции 'my_*' параметр **kwargs .

 def foo(data, functions_list, **kwargs): for my_function in functions_list: print(my_function(data, **kwargs)) def my_sum(a, b, **kwargs): return a + b def my_sub(a, c, **kwargs): return a - c foo(0, [my_sum, my_sub], b=3, c=10) 

Python автоматически анализирует kwargs устанавливая параметры b and c где он имеет значение.

Другой подход может быть следующим:

 def foo(data, function_list, **kwargs): function_dict = { "func_1": func_1, "func_2": func_2 } for func_i in function_list: print function_dict[func_i](data, **kwargs) def func_1(data, **arg): filtered_argument = {key: value for key, value in arg.items() if key.startswith('par_1')} return list([data, filtered_argument]) def func_2(data, **arg): filtered_argument = {key: value for key, value in arg.items() if key.startswith('par_2_')} return list([data, filtered_argument]) data = [1,2,3] foo(data, ['func_1', 'func_2'], par_1='some_par', par_2_0=5, par_2_1=11) 

Вывод:

 [[1, 2, 3], {'par_1': 'some_par'}] [[1, 2, 3], {'par_2_0': 5, 'par_2_1': 11}] 

Я уверен, что вы можете импровизировать свой текущий код, поскольку он становится таким же уродливым.

Мне нравится подход @ COLDSPEED, но хочу представить еще одно решение. Передать всегда 3 значения: function, args, keyword args:

Применение:

 foo( func_1, ('some_par',), {}, func_2, (5, 11), {}, ) 

Реализация (синтаксис Python3):

 def foo(*args3): while args3: func, args, kwargs, *args3 = args3 func(*args, **kwargs) 

Подходом будет третий аргумент foo позиционного аргумента и перейдите в список аргументов с списком функций:

 def foo(data, functions_list, args): for func, arg in zip(functions_list, args): print(func(data, arg)) def func1(data, par_1): return 'func1 called with {}'.format(par_1) def func2(data, par_2): return 'func2 called with {}'.format(par_2) foo('some_data', [func1, func2], [ {'par_1_1': 11, 'par_1_2': 12}, {'par_2_1': 21, 'par_2_2': 22} ]) 

zip() используется для сопоставления каждой функции с соответствующими аргументами.

Вывод:

 func1 called with {'par_1_1': 11, 'par_1_2': 12} func2 called with {'par_2_1': 21, 'par_2_2': 22} 

Вы можете сделать что-то подобное, «закрыть» каждый параметр для функции в элементе списка, а затем позволить «foo» разбить его назад:

 def foo(data, functions_list, kwarg): for func_i, args in zip(functions_list, kwarg): func_i(data, **args) def func_1(data, par_1): print("func_1 %s %s" % (data, par_1)) def func_2(data, par_2_0, par_2_1): print("func_2 %s " "%s %s" % (data, par_2_0, par_2_1)) data = "Some Data" foo(data, [func_1, func_2], [{"par_1":'some_par'}, {"par_2_0":5, "par_2_1":11}])