Site original : Sam & Max: Python, Django, Git et du cul
En Python les fonctions sont des objets de premier ordre. On peut les manipuler, copier les références, les supprimer…
Exemple :
# On definit une fonction. # Jusqu'ici tout va bien... def pizza(): return "miam" print(pizza()) ## miam # On peut assigner la référence de # la fonction à une variable. delice = pizza # Et utiliser la fonction depuis la variable print(delice()) ## miam # On peut même supprimer la variable # originale. del pizza print(delice()) ## miam pizza() --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-3-dc0f1f08233f> in <module>() ----> 1 pizza() NameError: name 'pizza' is not defined
La fonction est un objet ordinaire qui peut donc se mettre dans une variable, mais aussi se passer en paramètre, se retourner comme valeur, etc. J’ai déjà expliqué ça dans le tuto sur les décorateurs plus en détail, mais un rappel ne fait pas de mal.
Cela veut dire que l’on peut mettre la référence d’une fonction dans une structure de données.
Par exemple dans une liste :
def pizza(): return "miam" def epinard(): return "miam aussi" def arepas(): return "decidement tout est miam" # On met les fonctions dans la liste : liste_de_fonctions = [pizza, epinard, arepas] # Et du coup on peut boucler sur les fonctions for func in liste_de_fonctions: print(func()) ## miam ## miam aussi ## decidement tout est miam # Le monde des listes s'ouvre à vous print(liste_de_fonctions[-1]()) ## decidement tout est miam f1, f2 = liste_de_fonctions[:2] print(f2()) ## miam aussi
Mais aussi dans un dictionnaire :
dico_de_fonction = { "choix1": pizza, "choix2": epinard, "choix3": arepas } print(dico_de_fonction["choix2"]()) ## miam aussi for key, func in dico_de_fonction.items(): print("%s: %s" % (key, func())) ## choix1: miam ## choix3: decidement tout est miam ## choix2: miam aussi
En fait, ça marche avec tout (les fonctions sont hashables) : les sets, les tuples, les deques…
On peut même faire un générateur qui yield des fonctions :
import random def fonctions_aleatoires(nombre, fonctions=liste_de_fonctions): for x in range(nombre): yield random.choice(liste_de_fonctions) for func in fonctions_aleatoires(5): print(func()) ## miam aussi ## miam ## decidement tout est miam ## miam ## miam aussi
Python n’a certes pas les capacités de Lisp ou même Javascript pour faire de la programmation fonctionnelle, mais les fonctions restent des objets très puissants dans ce langage.
D’ailleurs, cet article est valable aussi pour les classes et les modules :)