Fonctions¶
Lors de l’écriture d’un programme, particulièrement lorsqu’on travaille à plusieurs sur un projet, il est naturel et recommandé de décomposer le problème global en différents sous-problèmes, chaque sous- problèmes étant plus facile à résoudre. La finalisation du travail consistera à agencer tous ces sous- problèmes les uns avec les autres.
De plus, il est fréquent qu’une séquence d’instructions particulières soit utilisée plusieurs fois. Il serait très préjudiciable en terme de clarté et de structure du programme de recopier l’intégralité de ces instructions.
Une fonction permet de regrouper une série d'instructions, ce qui facilite la compréhension du code.
Le mot clé def
est utilisé pour définir des fonctions en Python
.
Attention
On vient de définir la fonction mais on ne l'a pas encore appelée. Pour l'exécuter il faut la nommer et passer les arguments requis.
Valeurs retournées¶
Par défaut une fonction en Python
retournera None
. Donc, même si cette fonction affiche une chaîne de caractère, elle ne renvoie pas une chaîne de caractère, elle retourne None
.
Question
Quelle sera la valeur retournée par la fonction ma_fonction
?
Une fonction peut retourner une ou plusieurs valeurs. Lorsqu'une fonction retourne une valeur elle n'affiche rien. Si on souhaite afficher les valeurs retournées il faut utiliser la fonction print
.
On peut déclarer des variables en dehors des fonctions, ces variables seront accessibles à l'intérieur des fonctions (définies dans le même fichier).
Questions
- Que se passe t'il si on exécute le code ci-dessous ?
- Quel peut être l'inconvénient d'utiliser une variable globale de cette manière ?
Il peut y avoir plus return, mais un seul sera exécuté.
def bonjour_binaire(genre):
if genre == "M":
return "Bonjour monsieur"
elif genre == "F":
return "Bonjour madame"
# appel
bonjour_binaire("F")
Paramètres et arguments¶
On peut ajouter un ou des paramètres lors de la définition d'une fonction :
Ici, on vient d'ajouter un paramètrenom
.
Lorsque l'on appelle la fonction ma_function_coucou
on passe la valeur en argument :
Ici 'John' est un argument de la fonction ma_function_coucou
.
Portée des variables¶
Il est très important de distinguer les variables globales et les variables locales.
Les variables déclarées dans une fonction sont effacées à la fin de la fonction. On dit que ce sont des variables locales. Il est donc impossible d'utiliser ces variables déclarées en dehors de la fonction elle- même.
Question
Que se passe t'il d'après vous si on exécute le code ci-dessous ?
Prototype et documentation¶
Le prototype doit décrire le rôle de la fonction, le type des paramètres et le type de la valeur de retour. Ces informations sont communément appelées le prototype de la fonction.
def somme(a, b):
"""La somme de deux nombres.
Renvoie la somme des deux nombres donnés en arguments
Paramètres
----------
a : int
première valeur à ajouter
b : int
deuxième valeur à ajouter
Renvoie
-------
int
La somme des deux arguments de la fonction
"""
return a + b
Maintenant, en tapant help(somme), vous aurez toutes les informations utilise pour utiliser la fonction.
help(somme)
Help on function somme in module __main__:
somme(a, b)
La somme de deux nombres.
Renvoie la somme des deux nombres donnés en arguments
Paramètres
----------
a : int
première valeur à ajouter
b : int
deuxième valeur à ajouter
Renvoie
-------
int
La somme des deux arguments de la fonction
Notez tout de même qu’en Python, il n’est pas nécessaire de préciser le type des paramètres ni le type de la variable retournée (typage dynamique).
Il est d’usage de documenter ses fonctions juste après la définition de celles-ci. On peut être un peu plus rigoureux sur le format de cette documentation. Pour de plus amples détails, vous pouvez consulter cette page https://peps.python.org/pep-0008/.
Préconditions et postconditions¶
On peut vouloir vérifier que des conditions qui sont sensées être satisfaites le sont effectivement, à l’aide du mécanisme d’assertion proposé par le langage Python. Prenons un exemple :
Dans cet exemple, trois instructions assert ont été utilisées pour vérifier les préconditions. Une telle instruction se compose d’une condition (une expression booléenne) éventuellement suivie d’une virgule et d’une phrase en langage naturel sous forme de chaîne de caractères.
L’instruction assert teste si la condition est satisfaite :
- Si c’est le cas, elle ne fait rien
- Sinon, elle arrête immédiatement l’exécution du programme en affichant une erreur AssertionError et éventuellement le texte associé.
De la même manière, on peut utiliser les assertions pour vérifier des conditions sur la valeur à retourner par la fonction ; on parle de postconditions. La syntaxe est la même, et on testera ces postconditions juste avant le return.
Tests d'assertion¶
Pour être sûr que notre fonction donne les bons résultats, on utilise des tests d’assertion (affirmation en anglais) qui renvoient une AssertionError
en cas d’erreur.
Il est extrêmement important de bien tester son code, cela permet entre autres au développeur de s'assurer (un minimum) de bien avoir le résultat attendu.
Nous verrons par la suite comment on peut tester son code en Python de manière plus approfondie.
Programmation fonctionnelle¶
Même si on peut voir certaines similitudes entre les fonctions Python et les fonctions mathématiques, les fonctions Python permettent une souplesse plus importante, par exemple on peut modifier des variables en dehors de la portée locale de la fonction (on parle d'effet de bord
). Certains langages de programmation dits fonctionnels
comme OCaml
ou Haskell
(surtout Haskell) utilisent des fonctions qui se rapprochent davantage des fonctions mathématiques.
Nous reviendrons sur ce point en Terminale.