107 votes

Comment écrire une fonction qui renvoie une autre fonction ?

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 rendre le volume d'un cylindre de hauteur h et le rayon r .

Je sais comment retourner valeurs à partir de fonctions en Python, mais comment puis-je retourner une autre fonction ?

206voto

Óscar López Points 97105

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 y height=5 :

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

Remarquez que pour retourner une fonction, il suffit de définir une nouvelle fonction à l'intérieur de la fonction et de la retourner à la fin - en prenant soin de passer les paramètres appropriés pour chaque fonction. Pour votre information, la technique consistant à retourner une fonction à partir d'une autre fonction est connue sous le nom de currying .

24voto

DaveIdito Points 1246

En utilisant des lambdas, également connues sous le nom de fonctions anonymes, vous pouvez faire abstraction de la fonction volume dans la fonction make_cylinder_volume_func à une seule ligne. En aucun cas différente 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 en utilisant 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 au curry :

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

10voto

Erotemic Points 1630

Je veux juste signaler que vous pouvez faire cela avec pymonad

 import pymonad 

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

 add5 = add(5)
 add5(4)
 9

2voto

R3ct0r Points 266

Je sais que j'arrive trop tard dans la soirée, mais je pense que cette solution pourrait vous intéresser.

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 documentation sur la façon dont partial travaux.

0voto

Rahul Vaidya Points 1

Voici un exemple massif qui couvre de nombreux cas d'arguments multiples uniques dans une seule fonction.

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'")

Ici, il faut d'abord appeler la fonction mathématique avec l'opération requise, puis utiliser la fonction renvoyée pour le calcul proprement dit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X