|
- Jouons avec les fonctions
- =========================
-
- Introduction
- ------------
-
- Reprenons ce qu'on a vu jusqu'ici.
-
- D'une part, on peut créer des variables en assignant des valeurs à celles-ci::
-
- # Création d'une variable `x` avec la valeur 4
- x = 4
-
- D'autre part, on peut définir et appeler des fonctions::
-
- # Définition de la fonction:
- def dire_bonjour(nom):
- print("Bonjour " + nom)
-
- # Appel
- dire_bonjour("Max")
-
- # Affiche: "Bonjour Max"
-
-
- Fonctions en tant que variables
- -------------------------------
-
- Il se trouve qu'en Python, on peut assigner des fonctions à des
- variables. C'est différent d'assigner le résultat de l'appel à une
- fonction à une variable, et ça permet de retarder l'appel:
-
- .. code-block:: python
-
- # Définition d'une fonction `dire_bonjour_en_français`
- def dire_bonjour_en_français(nom):
- print("Bonjour " + nom)
-
- # Définition d'une fonction `dire_bonjour_en_anglais`
- def dire_bonjour_en_anglais(nom):
- print("Hello " + nom)
-
- # Assigne une fonction à la variable - aucune fonction
- # n'est appelée à ce stade.
- ma_fonction_qui_dit_bonjour = dire_bonjour_en_français
-
- # Appel de la fonction (retardé)
- ma_fonction_qui_dit_bonjour("Max")
-
- # Affiche: Bonjour Max
-
-
- De façon cruciale, notez que l'on n'a *pas* mis de parenthèses à droite
- lorsqu'on a créé la variable `ma_fonction_qui_dit_bonjour`.
-
- On peut donc dire que lorsqu'on définit une fonction avec ``def ma_fonction()`` et un corps:
- il y a en réalité deux étapes:
-
- 1. Python stocke le corps de la fonction quelque part
- 2. Il assigne le corps de celle-ci à une variable dont le nom est ``ma_fonction``.
-
- En Python, il est assez fréquent d'utiliser de code tel que celui-ci, souvent avec un dictionnaire::
-
- fonctions_connues = {
- "français": dire_bonjour_en_français,
- "anglais": dire_bonjour_en_anglais,
- }
-
- # Ici on stocke la langue parlée par l'utilisateur
- # et son prénom
- langue_parlée = ...
- prénom = ....
-
- if langue_parlée in fonctions_connues:
- fonction = fonctions_connues[langue_parlée]
- fonction(prénom)
-
-
- Fonctions en tant qu'argement d'autres fonctions
- ------------------------------------------------
-
- On a vu en début de chapitre qu'on peut assigner des fonctions à des variables.
-
- Du coup, rien n'empêche de passer des fonctions en *argument* d'autres fonctions.
-
- Par exemple::
-
- def appelle_deux_fois(f):
- f()
- f()
-
-
- def crier():
- print("Aline !")
-
- appelle_deux_fois(crier)
-
- # Affiche:
- # Aline !
- # Aline !
-
-
- Fonctions imbriquées
- --------------------
-
- On peut aussi définir une fonction dans une autre fonction::
-
-
- def affiche_message(message):
- def affiche():
- print(message)
- affiche()
-
- affiche_message("Bonjour")
- # affiche: Bonjour
-
- Deux notes importantes:
-
- Premièrement, la fonction `affiche()` qui est imbriquées dans `affiche_message()` n'est pas
- accessible à l'éxtérieur de la fonction qui la contient. En d'autres termes, ce code
- ne fonctionne pas::
-
- def affiche_message(message):
- def affiche():
- print(message)
-
- affiche()
- # NameError: 'affiche' is not defined
-
- C'est un mécanisme similaire aux :ref:`portées des variables <portées-des-variables>` vu précédemment.
-
- Deuxièment, la fonction `affiche()` à l'intérieur de `affiche_message()`
- a accès à l'argument `message` de la fonction `affiche_message`. On appelle
- ça une "closure".
-
-
-
- Fonctions retournant des fonctions
- ----------------------------------
-
- En réalité, on combine souvent les closures avec des fonctions qui
- retournent d'autres fonctions::
-
-
- def fabrique_fonction_qui_additionne(n):
- def fonction_résultat(x):
- return x + n
- return fonction_résultat
-
-
- additionne_2 = fabrique_fonction_qui_additionne(2)
- y = additionne_2(5)
- print(y)
- # Affiche: 7
-
-
- Un autre paradigme
- -------------------
-
- Le fait qu'on puisse traiter les fonctions comme n'importe quelle
- autre valeur (c'est-à-dire les assigner à des variables, les passer
- en argument et les retourner), est caractéristique des langages
- dits "fonctionnels". Python est donc **à la fois** un
- langages *impératif*, *objet* et *fonctionnel*. On dit que
- c'est un langage *multi-paradigme*.
|