2016-02-26 2 views
1

Довольно очевидно, что подразумевается под h (x, y, z) = f (x, y) * g (y, z). Я хотел бы иметь устройство в Python, чтобы сделать что-то подобное, как:Умножение функций многих параметров в Python

fmul(f1(x,y),f2(y,z)) -> lambda x,y,z: f1(x,y)*f2(y,z) 
fmul(f1(x,y),f2(z,y)) -> lambda x,y,z: f1(x,y)*f2(z,y) 

и так работать повсеместно, в зависимости от имен параметров. Конечно, он не будет работать так, как он написан в псевдокоде выше, потому что Python сначала попытается оценить вызовы f1 и f2, и поскольку они будут сделаны с некоторыми именами переменных вместо значений, это приведет к созданию NameError. Есть ли способ передать эти имена переменных без изменений в определении лямбда, чтобы я получил правильный функциональный объект с четко определенным порядком параметров? Я предполагаю, что было бы относительно легко сделать на языке, таком как Lisp, с макросами и символами, но как это сделать в Python? Самое близкое, что я нашел для решения, - это использовать модуль проверки для извлечения параметров функции, но это строки, поэтому мне пришлось бы составлять выражение лямбда путем конкатенации строк, а затем оценивать это. Разве нет более простого пути?

+0

Являются ли имя параметра фиксированным (т.е. всегда 'x',' y' и 'z'), или они могут быть чем-нибудь? Вы всегда вызываете 'f1' с' x' и 'y', только с неизвестным порядком аргументов? – univerio

+0

В идеале я бы не хотел полагаться на имена параметров, вместо этого имел бы некоторый способ сообщить fmul «сделать второй аргумент f1 равным первому аргументу f2» и так далее. Конечно, это будет дисквалифицировать метод проверки, о котором я упоминал. Кроме того, количество аргументов может быть любым, не обязательно 2 в обеих функциях. – Zeissmann

+0

Python Язык не имеет такого уровня символической манипуляции. Вы можете взглянуть на [SymPy] (www.sympy.org). – chepner

ответ

1

Пропустите функции в качестве аргументов:

def fmul(f1, f2): 
    return (lambda x,y,z: f1(x,y)*f2(y,z)) 
+0

Где значения, возникающие при выполнении 'f1' и' f2'? –

+0

@ColinBasnett лямбда –

+0

@ColinBasnett Они исходят от вызывающей функции, которая возвращается. 'newfun = fmul (somefun, someotherfun)' then 'newfun (x, y, z)'. – Barmar

0

Если вы знаете имена аргументов предварительно (и при условии, вы можете переопределить f1 и f2), вы можете сделать это с использованием ключевых аргументов без отвода с inspect:

def f1(x, y, **kwargs): 
    return x + y 


def f2(z, y, **kwargs): 
    return z - y 


def fmul(f1, f2): 
    return lambda x, y, z: f1(x=x, y=y, z=z) * f2(x=x, y=y, z=z) 
Смежные вопросы