Come faccio a scrivere una funzione che restituisce un'altra funzione?

2013-01-10 python function functional-programming currying

In Python, vorrei scrivere una funzione make_cylinder_volume(r) che restituisce un'altra funzione. La funzione restituita deve essere richiamabile con un parametro h e restituire il volume di un cilindro con altezza h e raggio r .

So come restituire i valori dalle funzioni in Python, ma come posso restituire un'altra funzione ?

Answers

Prova questo, usando Python:

import math
def make_cylinder_volume_func(r):
    def volume(h):
        return math.pi * r * r * h
    return volume

Usalo in questo modo, ad esempio con radius=10 e height=5 :

volume_radius_10 = make_cylinder_volume_func(10)
volume_radius_10(5)
=> 1570.7963267948967

Notare che restituire una funzione era una semplice questione di definire una nuova funzione all'interno della funzione e restituirla alla fine - facendo attenzione a passare i parametri appropriati per ciascuna funzione. Cordiali saluti, la tecnica per restituire una funzione da un'altra funzione è nota come curry .

Voglio solo sottolineare che puoi farlo con pymonad

 import pymonad 

 @pymonad.curry
 def add(a, b):
     return a + b

 add5 = add(5)
 add5(4)
 9

Usando lambdas, note anche come funzioni anonime, puoi sottrarre la funzione del volume all'interno di make_cylinder_volume_func su una singola riga. In nessun modo diverso dalla risposta di Óscar López, la soluzione che utilizza lambda è ancora in un certo senso "più funzionale".

Ecco come puoi scrivere la risposta accettata usando un'espressione lambda:

import math
def make_cylinder_volume_fun(r):
    return lambda h: math.pi * r * r * h

E poi chiama come faresti con qualsiasi altra funzione al curry:

volume_radius_1 = make_cylinder_volume_fun(1)
volume_radius_1(1) 
=> 3.141592653589793

So di essere troppo tardi per la festa, ma penso che potresti trovare interessante questa soluzione.

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

Ecco la documentazione su come funziona partial .

Related