Передача функций и их аргументов в другую функцию

У меня есть типы дерева подфункций:

  • один без каких-либо параметров (аргументов),
  • второй с одним параметром
  • третий с несколькими параметрами (кортеж)

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

Пример:

 def no_arg()
 def one_arg(a)
 def multiple_args(a, b, c, e, f)

 # execution of function_results_sum:
 function_results_sum(
     no_arg, one_arg, multiple_args,
     one_arg=23,
     multiple_args=(1, 2, 3, 4, 5))

Что я сделал до сих пор:

def no_arg():
    return 5

def ident(x):
    return x

def mult(x, y):
    return x * y    

def function_results_sum(*args, **kwargs):
        return no_arg() + ident(kwargs[ident.__name__]) + mult(*kwargs[mult.__name__])   

Приведенный выше код передает аргументы каждой подфункции, но имена подфункций жестко закодированы. Я хотел бы изменить текущий код, чтобы иметь возможность получать имена функций из * args. Ниже я написал псевдокод, выражающий более менее то, что я пытаюсь достичь:

def function_results_sum(*args, **kwargs):
    for functionName in args:
        result = sum(funcionName(kwargs))
    return result

Я уже целый день боролся с этой проблемой, поэтому, пожалуйста, не пишите мне, что "использование Google не повредит";)

3 ответа

Решение

Примерно так будет работать:

def no_arg():
    return 5

def one_arg(x):
    return x

def multiple_args(x, y):
    return x * y

def function_results_sum(*args, **kwargs):
    result = 0
    for func in args:
            result += func(*kwargs[func.__name__])
    return result

Выход:

function_results_sum(
    no_arg, one_arg, multiple_args,
    no_arg=(),
    one_arg=(23, ),
    multiple_args=(1,5))

33

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

Если вы не хотите указывать что-либо для функций без аргументов, вы можете дважды проверить, указано ли имя функции в kwargs:

def function_results_sum(*args, **kwargs):
    result = 0
    for func in args:
        if func.__name__ i kwargs:
            result += func(*kwargs[func.__name__])
        else:
            result += func()
    return result

Пост R Nar - это именно то, чего я пытался добиться. Я добавил дополнительный оператор if, чтобы проверить, является ли kwarg целым числом или кортежем. Спасибо, что не обязательно помещать все **kwargs в кортеж. Спасибо ребята за помощь!

def function_results_sum(*args, **kwargs):
    result = 0
    for func in args:
        if func.__name__ in kwargs:
            if type(kwargs[func.__name__]) == int:
                result += func(kwargs[func.__name__])
            elif type(kwargs[func.__name__]) == tuple:
                result += func(*kwargs[func.__name__])
        else:
            result += func()
    return result

result = function_results_sum(no_arg, ident, mult, ident=2, mult=(3, 4))
print(result)

Найдя "Python определить количество аргументов для переданной функции", я нашел Как я могу найти количество аргументов функции Python?

Я уверен, что вам не нужен ключ **kwars, синтаксис значения, поэтому я использую func_list регулярный арг и *args

from inspect import signature


def function_results_sum(func_list, *args):

    arg_gen = (e for e in args)

    return sum([func(*(next(arg_gen)
                       for _ in range(len(signature(func).parameters))))
               for func in func_list])

function_results_sum([no_arg, ident, mult], 7,8,9)
84  

ввод может быть сделан более плоским, анализируя * args для Functions и (предполагаемые) аргументы (ничего не типа Function)

from inspect import signature
import types


def function_results_sum(*args):

    func_gen = (e for e in args if isinstance(e, types.FunctionType))

    arg_gen = (e for e in args if not isinstance(e, types.FunctionType))

    return sum(func(*(next(arg_gen)
                       for _ in range(len(signature(func).parameters))))
               for func in func_gen)

function_results_sum(no_arg, ident, mult, 10,6,90)
555

порядок функций и порядок аргументов важны, но могут чередоваться отдельно:

function_results_sum(no_arg, 10, ident, 6, 90, mult)
Out[399]: 555
Другие вопросы по тегам