Em Python, gostaria de escrever uma função make_cylinder_volume(r)
que retorne outra função. Essa função retornada deve ser chamada com um parâmetro h
e retornar o volume de um cilindro com altura h
e raio r
.
Eu sei como retornar valores de funções em Python, mas como faço para retornar outra função ?
python
function
functional-programming
currying
Julian Das
fonte
fonte
Respostas:
Experimente isso, usando Python:
import math def make_cylinder_volume_func(r): def volume(h): return math.pi * r * r * h return volume
Use-o assim, por exemplo, com
radius=10
eheight=5
:volume_radius_10 = make_cylinder_volume_func(10) volume_radius_10(5) => 1570.7963267948967
Observe que retornar uma função era uma simples questão de definir uma nova função dentro da função e retorná-la no final - tendo o cuidado de passar os parâmetros apropriados para cada função. FYI, a técnica de retornar uma função de outra função é conhecida como currying .
fonte
10
você passou está armazenado em algum lugar? Quando é coletado o lixo?Usando lambdas, também conhecidas como funções anônimas, você pode abstrair a
volume
função dentro demake_cylinder_volume_func
em uma única linha. Em nada diferente da resposta de Óscar López, a solução usando lambda ainda é em certo sentido 'mais funcional'.É assim que você pode escrever a resposta aceita usando uma expressão lambda:
import math def make_cylinder_volume_fun(r): return lambda h: math.pi * r * r * h
E então chame como você faria qualquer outra função curry:
volume_radius_1 = make_cylinder_volume_fun(1) volume_radius_1(1) => 3.141592653589793
fonte
lambda h:
fosse retirada a função funcionaria da mesma forma?return
tentará avaliar o resultado antes de retornar e, como é um monte de variáveis, retornará algum valor flutuante (tente retornar uma função e ela funcionará).lambda
informa que o código a seguir não deve ser avaliado e também que o escopo da variável r será preservado nas funções retornadas pormake_cylinder..
.Só quero salientar que você pode fazer isso com pymonad
import pymonad @pymonad.curry def add(a, b): return a + b add5 = add(5) add5(4) 9
fonte
from functools import partial add5 = partial(add, 5)
Faz exatamente o mesmoSei que estou muito atrasado para a festa, mas acho que você pode achar esta solução interessante.
from math import pi from functools import partial def cylinder_volume(r, h): return pi * r * r * h make_cylinder_with_radius_2 = partial(cylinder_volume, 2) make_cylinder_with_height_3 = partial(cylinder_volume, h=3) print(cylinder_volume(2, 3)) # 37.6991118431 print(make_cylinder_with_radius_2(3)) # 37.6991118431 print(make_cylinder_with_height_3(2)) # 37.6991118431
Aqui está a documentação sobre como
partial
funciona.fonte
Aqui está um grande exemplo que cobre muitos dos casos de argumentos múltiplos em uma função
def maths(var='NA'): if var.lower() == 'add': def add(*args): return "Sum is : "+str(sum(args)) return add elif var.lower() == 'substract': def substract(a,b): if a>b: return "Difference is : "+str(a-b) else: return "Difference is : "+str(b-a) return substract elif var.lower() == 'multiply': def multiply(*args): temp = 1 for x in args: temp = temp*x return "multiplication is : "+str(temp) return multiply elif var.lower() == 'divide': def divide(a,b): return "Division is : "+str(a/b) return divide else: print("Please choose one of given operations: 'add','substract','multiply','divide'")
Aqui, primeiro chame a função matemática com a operação necessária e, em seguida, use a função retornada para o cálculo real
fonte