En Python, j'aimerais écrire une fonction make_cylinder_volume(r)
qui renvoie une autre fonction. Cette fonction retournée doit pouvoir être appelée avec un paramètre h
et renvoyer le volume d'un cylindre avec hauteur h
et rayon r
.
Je sais comment renvoyer des valeurs à partir de fonctions en Python, mais comment renvoyer une autre fonction ?
python
function
functional-programming
currying
Julian Das
la source
la source
Réponses:
Essayez ceci, en utilisant Python:
import math def make_cylinder_volume_func(r): def volume(h): return math.pi * r * r * h return volume
Utilisez-le comme ceci, par exemple avec
radius=10
etheight=5
:volume_radius_10 = make_cylinder_volume_func(10) volume_radius_10(5) => 1570.7963267948967
Notez que retourner une fonction consistait simplement à définir une nouvelle fonction à l'intérieur de la fonction et à la renvoyer à la fin - en prenant soin de passer les paramètres appropriés pour chaque fonction. Pour info, la technique de renvoi d'une fonction à partir d'une autre fonction est connue sous le nom de currying .
la source
10
vous avez passé est stocké quelque part? Quand est-il ramassé?À l'aide de lambdas, également appelées fonctions anonymes, vous pouvez extraire la
volume
fonction à l'intérieur dumake_cylinder_volume_func
sur une seule ligne. En aucun cas différent de la réponse d'Óscar López, la solution utilisant lambda est toujours dans un sens «plus fonctionnelle».Voici comment vous pouvez écrire la réponse acceptée à l'aide d'une expression lambda:
import math def make_cylinder_volume_fun(r): return lambda h: math.pi * r * r * h
Et puis appelez comme vous le feriez pour n'importe quelle autre fonction curry:
volume_radius_1 = make_cylinder_volume_fun(1) volume_radius_1(1) => 3.141592653589793
la source
lambda h:
était supprimée, la fonction fonctionnerait-elle de la même manière?return
va essayer d'évaluer le résultat avant de retourner, et parce que c'est un tas de variables, il retournera une valeur flottante (essayez de renvoyer une fonction et cela fonctionnera).lambda
indique que le code suivant ne doit pas être évalué et que la portée de la variable r sera conservée dans les fonctions renvoyées parmake_cylinder..
.Je veux juste souligner que vous pouvez le faire avec pymonad
import pymonad @pymonad.curry def add(a, b): return a + b add5 = add(5) add5(4) 9
la source
from functools import partial add5 = partial(add, 5)
Fait exactement la même choseJe sais que je suis trop tard à la fête, mais je pense que vous pourriez trouver cette solution intéressante.
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
Voici la documentation sur le
partial
fonctionnement.la source