Les fonctions¶
Une fonction permet d’identifier une séquence de traitements par un nom. Une fonction peut alors être appelée par son nom à plusieurs endroits dans un programme pour réaliser ces traitements. Il s’agit ainsi de rendre un programme plus compréhensible tout en évitant de dupliquer une séquence à plusieurs points du programme. Un autre intérêt d’une fonction est qu’elle peut être écrite par un programmeur et être utilisée dans un code source écrit par un autre programmeur qui n’a pas besoin de connaître précisément le code exécuté par la fonction si son nom et sa documentation sont suffisamment explicites.
Appeler une fonction¶
Il existe beaucoup de fonctions déjà fournies avec l’environnement d’exécution
Python. On les appelle les builtin functions
. La plus célèbre d’entre-elles
est sans doute print()
. Elle affiche sur la sortie standard du programme
une message fourni en paramètre. Pour appeler une fonction dans un programme,
il faut préciser son nom et passer entre parenthèses la liste des paramètres.
La fonction print()
accepte en paramètre ce qu’elle doit afficher :
# appel de la fonction print
print("Bonjour le monde")
Il est possible de passer plusieurs paramètres à la fonction print()
. Dans
ce cas, il faut séparer la valeur des paramètres par une virgule.
# Cet appel affiche : Bonjour le monde
print("Bonjour", "le", "monde")
Il est également possible d’appeler la fonction print()
sans aucun paramètre.
La fonction se contentera d’afficher une ligne vide sur la sortie standard.
Même s’il n’y pas de paramètre, les parenthèses sont obligatoires en Python 3.
# Cet appel affiche une ligne vide
print()
Si un paramètre peut être une valeur directement donnée par le programme, un paramètre peut aussi être une variable. Dans ce cas, c’est la valeur contenue dans la variable qui est passée à la fonction :
msg = "hello"
# Cet appel affiche : hello
print(msg)
Un paramètre peut aussi être une expression. Dans ce cas, c’est le résultat de l’évaluation de l’expression qui est passé à la fonction :
x = 2
# Cet appel affiche : Le résultat est 8
print("Le résultat est", x**3)
Une fonction peut retourner une valeur, c’est-à-dire fournir le résultat de son
traitement. Cette valeur peut être affectée à une variable. Par exemple,
la fonction abs()
retourne la valeur absolue du nombre qui lui est passé
en paramètre :
x = -2
valeur_absolue = abs(x)
# affiche 2
print(valeur_absolue)
L’appel d’une fonction peut être passé en paramètre d’une autre fonction. Dans ce cas, c’est la valeur retournée par l’appel de la fonction qui est passée à l’autre fonction.
# afficher 2
print(abs(-2))
Ce type d’écriture permet une plus grande concision dans l’expression.
Note
Une fonction qui ne produit aucun résultat est souvent appelée une procédure. On dit également qu’elle agit par effet de bord.
En Python, essayer d’affecter le résultat de l’appel d’une procédure à une
variable ne produit pas d’erreur. La valeur de la variable est simplement
positionnée à None
.
# print est une procédure, elle ne retourne aucune valeur
x = print()
# affiche None
print(x)
Les fonctions utiles dans la console Python¶
Parmi les builtin functions
, il existe cinq fonctions
qui sont très pratiques lorsqu’on exécute des instructions Python dans une
console :
exit()
etquit()
Ces fonctions permettent d’arrêter la console Python
>>> quit()
repr(o)
Affiche des informations sur l’élément passé en paramètre.
>>> repr(print) '<built-in function print>'
L’interpréteur appelle implicitement cette fonction à chaque fois que vous tapez la touche Entrer. L’interpréteur évalue l’expression saisie et, si elle produit un résultat, il affiche la chaîne de caractères retournée par l’appel à
repr(o)
auquel est passé en paramètre le résultat de l’expression.>>> print '<built-in function print>'
help(o)
Affiche la documentation de l’élément passé en paramètre. La console passe généralement en mode affichage de l’aide. Pour sortir de ce mode, il faut presser la touche Q pour quit.
>>> help(print)
dir(o)
Retourne une liste des attributs et des méthodes de l’élément passé en paramètre. Nous verrons beaucoup plus tard que, dans le langage Python, tout est un objet. Un objet se définit par ses attributs (les données) et par ses méthodes (son comportement).
>>> dir(print) ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', ' __init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']
Les fonctions de conversion de type¶
Les fonctions int()
, float()
,
bool()
et str()
permettent de réaliser des conversions
d’un type à l’autre.
Convertir en nombre¶
La conversion entre entiers et nombres à virgule flottante :
>>> r = 3.5
>>> int(r)
3
>>> n = 2
>>> float(n)
2.0
Il est également possible de convertir une chaîne de caractères :
>>> int("3")
3
>>> float("5.25")
5.25
Dans ce cas, la fonction int()
accepte un deuxième paramètre
indiquant la base du nombre (par défaut la base est 10) :
>>> int("10", 8)
8
>>> int("0xFF", 16)
255
Prudence
Pour la conversion en nombre, la chaîne de caractères peut contenir des espaces
avant et après mais si elle ne représente pas un nombre valide, les fonctions
int()
et float()
produisent une erreur
ValueError
.
Convertir en valeur booléenne¶
La fonction bool()
permet de convertir en valeur booléenne.
Elle produit la valeur True
pour un nombre différent de 0 et
pour une chaîne de caractères non vide. La valeur None
produit
toujours la valeur False
.
>>> bool(42)
True
>>> bool(0)
False
>>> bool("hello")
True
>>> bool("False")
True
>>> bool("")
False
>>> bool(None)
False
Tester le type d’une valeur ou d’une variable¶
La fonction type()
permet de connaître le type d’une variable ou d’une valeur:
>>> type(1)
<class 'int'>
>>> type(2.2)
<class 'float'>
>>> type("hello")
<class 'str'>
>>> type(1j)
<class 'complex'>
Cette fonction retourne un objet représentant le type de la valeur (nous reviendrons plus tard sur la notion de programmation objet).
Si vous voulez tester le type d’une variable ou d’une valeur, vous pouvez utiliser
la fonction isinstance()
qui prend la valeur à tester comme premier paramètre
et le type attendu comme second paramètre.
>>> isinstance(True, bool)
True
>>> isinstance(1, int)
True
>>> isinstance(2.2, float)
True
>>> isinstance("hello", str)
True
>>> isinstance("hello", bool)
False
>>> isinstance(2.3, int)
False
>>> isinstance(True, float)
False
>>> isinstance(1, str)
False
Exercices¶
Exercice : comparaison à la moyenne
Écrivez un programme qui demande à l’utilisateur sa taille puis qui indique l’écart en centimètres par rapport à la moyenne. On pourra utiliser comme moyenne 1m75.
Pour réaliser ce programme, vous allez avoir besoin de la fonction
input()
. Cette fonction accepte en paramètre le message à afficher
à l’utilisateur. L’appel à cette fonction bloque le programme et attend
que l’utilisateur saisisse une valeur puis tape sur Entrer. La
fonction retourne alors la valeur saisie sous la forme d’une chaîne
de caractères.
Exemples d’utilisation du programme :
Quelle est votre taille ? 1.70
Vous avez un écart de -5 centimètres par rapport à la moyenne
Quelle est votre taille ? 1.75
Vous avez un écart de 0 centimètres par rapport à la moyenne
Exercice : conversion Fahrenheit / Celsius
Écrivez un programme qui demande à l’utilisateur de saisir une température en degré Fahrenheit et qui affiche le résultat de la conversion en degré Celsius avec un seul chiffre après la virgule.
La formule à appliquer :
Exemple d’utilisation du programme :
Température Fahrenheit ? 42
Une température de 42.0°F correspond à 5.5°C
Exercice : QCM en invite de commande
Écrivez un programme qui pose des questions pour lesquelles l’utilisateur doit fournir une réponse. Pour chaque réponse correcte, l’utilisateur marque un point. À la fin, le programme indique le nombre de réponses justes et le nombre de réponses fausses.
Exemple d’utilisation du programme :
Quel est ton nom ?
Sir Robin de Camelot.
Quelle est ta quête ?
Trouver le Saint Graal.
Quelle est la capitale de la Syrie ?
Je sais pas ça !
Réponses correctes : 2
Réponses incorrectes : 1
Déclarer une fonction¶
L’intérêt principal des fonctions est de pouvoir organiser un programme en le décomposant en traitements de granularité plus faible. Ces traitements deviendront des fonctions dont le nom et la documentation amélioreront la lisibilité et la maintenabilité.
Pour déclarer sa propre fonction, on commence par préciser sa signature.
Cette signature est délimitée par le mot-clé def
et deux-points :
. Elle
donne le nom de la fonction et la liste des paramètres. Puis vient le corps de
la fonction, c’est-à-dire le code à exécuter lorsque cette fonction est appelée.
Pour délimiter le corps d’une fonction, Python utilise l’indentation. Chaque
ligne de la fonction commence par un certain nombre d’espaces (généralement quatre).
Cela donne, à la fois, une indication visuelle au lecteur et à l’interpréteur
de code.
Note
Le nom d’une fonction suit la même convention que le nom des variables. Il s’écrit en lettres minuscules et les mots sont séparés par un trait inférieur (underscore) suivant la notation dite du snake case.
def dire_bonjour_a(nom):
print("Bonjour", nom)
Un paramètre est simplement indiqué par son nom qui peut être ensuite utilisé dans le corps de la fonction. Un paramètre a pour valeur celle qui est donnée à chaque appel de la fonction.
Il est ensuite possible d’appeler la fonction qui a été déclarée :
# affiche Bonjour David
dire_bonjour_a("David")
Note
Le corps d’une fonction Python doit contenir au moins une ligne. Si pour
une raison ou une autre, vous voulez déclarer une fonction mais que vous
voulez laisser le corps vide (votre fonction ne réalise aucun traitement), alors
vous devez utiliser le mot-clé pass
:
def ma_fonction_qui_ne_fait_rien():
pass
Documenter une fonction¶
Pour écrire la documentation d’une fonction, il suffit d’ajouter une chaîne
de caractères directement à la suite de la déclaration de la signature de la
fonction. On appelle ce texte la docstring
. C’est ce texte qui
est affiché lorsqu’on passe le nom de la fonction à la fonction help()
.
def dire_bonjour_a(nom):
"""Affiche un message qui dit bonjour au nom qui est passé en
paramètre"""
print("Bonjour", nom)
>>> help(dire_bonjour_a)
Les valeurs de retour¶
Pour qu’une fonction retourne une valeur, il faut utiliser le mot-clé return
suivi de la valeur à retourner.
def creer_nom(prenom, nom):
nom_complet = prenom + " " + nom
return nom_complet
La valeur à retourner peut être le résultat d’une expression. Cela evite souvent d’avoir recours à des variables intermédiaires :
def creer_nom(prenom, nom):
return prenom + " " + nom
Le mot-clé return
interrompt immédiatement le traitement de la fonction et
retourne la valeur au programme appelant. Si vous écrivez du code après un return
,
il ne sera jamais exécuté.
def creer_nom(prenom, nom):
return prenom + " " + nom
print("Cette instruction ne sera jamais executée")
Une fonction peut retourner plusieurs valeurs. C’est le cas, par exemple, de la
fonction standard divmod()
qui retourne à la fois le résultat de la division
et le reste de la division. Python permet de récupérer ces valeurs dans deux
variables différentes :
resultat, reste = divmod(10, 3)
print("Le resultat de la division de 10 par 3 est", resultat, "et le reste est", reste)
# Le resultat de la division de 10 par 3 est 3 et le reste est 1
Nous pourrions réécrire sans difficulté la fonction divmod()
:
def divmod(numerateur, denominateur):
resultat = numerateur // denominateur
reste = numerateur % denominateur
return resultat, reste
Le mot-clé return
peut également être employé seul pour signaler la fin
d’une procédure. Dans cas, l’exécution de return
interrompt immédiatement
la procédure sans retourner de valeur.
Les paramètres nommés¶
Python supporte les paramètres nommés pour une fonction. Cela signifie que vous pouvez, lors de l’appel d’une fonction, préciser le nom et la valeur du paramètre.
def dire_bonjour_a(nom):
print("Bonjour", nom)
dire_bonjour_a(nom="David")
Cela peut s’avérer utile pour une fonction qui accepte plusieurs paramètres. En effet, il n’est pas toujours facile de se souvenir de l’ordre exact des paramètres ni de leur signification. En nommant les paramètres au moment de l’appel, leur rôle devient plus explicite et nous ne sommes plus obligés de respecter l’ordre de leur déclaration :
def dire_bonjour_a(prenom, nom):
print("Bonjour", prenom, nom)
dire_bonjour_a(nom="Gayerie", prenom="David")
Note
Vous pouvez appeler un fonction en passant des paramètres et des paramètres nommés. Dans ce cas, les paramètres nommés doivent être placés à la fin de la liste des paramètres.
Valeur par défaut des paramètres¶
Python autorise une fonction à avoir une valeur par défaut pour un ou plusieurs
de ses paramètres. Ainsi le programme qui appelle la fonction peut omettre de
donner une valeur pour ces paramètres. Cela permet de rendre certains paramètres
optionnels. On précise la valeur d’un paramètre après le signe =
.
def dire_bonjour_a(nom, message="Bonjour"):
print(message, nom)
# affiche Bonjour David
dire_bonjour_a("David")
# affiche Bonsoir David
dire_bonjour_a(message="Bonsoir", nom="David")
Fonction et portée des variables¶
Une fonction peut accepter des paramètres et une fonction peut déclarer des variables :
def calcul_prix_ttc(prix_ht, taux_tva = 20):
# déclaration de la variable tva
tva = prix_ht * taux_tva / 100
tva = round(tva, 2)
return prix_ht + tva
Astuce
La fonction round()
arrondie un nombre (le premier paramètre) avec une
précision après la virgule donnée par le second paramètre.
Dans l’exemple ci-dessus, la fonction calcul_prix_ttc()
utilise la variable
tva
pour stocker le calcul de la TVA et réaliser un arrondi. Cette variable
est liée à l’exécution de la fonction calcul_prix_ttc()
. Cela signifie
qu’elle n’existe pour l’interpréteur qu’au moment de l’exécution de la
fonction. Dès que la fonction se termine, la variable et sa valeur ne sont plus
accessibles. On dit que la portée de la variable tva
est limitée à la
fonction calcul_prix_ttc()
. Donc cette variable n’existe pas dans le reste
du programme.
# Génère une erreur NameError car la variable tva n'existe pas
print(tva)
calcul_prix_ttc(100)
# Génère une erreur NameError car la variable tva n'existe pas
print(tva)
Mais que se passe-t-il si le programme déclare et utilise une variable tva
avant et après l’appel à calcul_prix_ttc()
tva = "ceci n'est pas vraiment le montant d'une tva"
calcul_prix_ttc(100)
# affiche: ceci n'est pas vraiment le montant d'une tva
print(tva)
Avec l’exemple précédent, on voit bien que la variable tva
n’est pas modifiée
par l’appel à la fonction calcul_prix_ttc()
car même si elle a un nom identique
à la variable utilisée dans cette fonction, il s’agit de variables différentes
pour l’interpréteur. On peut déclarer et utiliser des variables
qui ont le même nom à condition qu’elles n’appartiennent pas à la même portée.
Exercices¶
Exercice : comparaison à la moyenne
Reprenez l’exercice qui permet de comparer une taille saisie avec la moyenne.
Créez trois fonctions dans le programme :
- demander_taille()
Cette fonction demande sa taille à l’utilisateur et retourne la valeur saisie sous la forme d’un nombre.
- comparer_taille()
Cette fonction compare une première taille à une seconde et donne la différence en centimètres. Le second paramètre a une valeur par défaut qui correspond à la moyenne de la taille.
- afficher_difference_moyenne()
Cette fonction prend en paramètre un écart de taille en centimètres et affiche l’information à l’utilisateur.
Exercice : fonction de conversion Fahrenheit / Celsius
Écrivez une fonction pour convertir une température en degré Fahrenheit en une température en degré Celsius.
Variable globale et fonction¶
Une variable qui est déclarée dans le fichier principal est aussi appelée variable globale car elle existe dans la mémoire jusqu’à la fin de l’exécution du programme.
Imaginons le programme suivant :
message="Bonjour"
def dire_bonjour_a(nom):
print(message, nom)
# Affiche Bonjour David
dire_bonjour_a("David")
La fonction dire_bonjour_a()
utilise la paramètre nom
mais aussi la
variable globale message
. Dans les deux cas, la fonction ne fait que lire
la valeur du paramètre et de la variable globale. Mais comment faire pour modifier
la valeur d’une variable globale dans le corps d’une fonction ?
Nous avons vu à la section précédente qu’il n’est pas possible de modifier directement une variable globale dans une fonction. Nous pouvons simplement créer une nouvelle variable avec le même nom ayant une portée limitée à la fonction. Pour nous en convaincre, essayons le programme suivant :
message = "Un message global"
def traiter_message():
message = "Un message local"
print(message)
print(message)
traiter_message()
print(message)
Ce programme produit le résultat suivant :
Un message global
Un message local
Un message global
Cela montre bien que la variable globale message
et la variable message
initialiser dans la fonction traiter_message()
sont bien distinctes.
En Python, il est tout de même possible de modifier une variable globale dans
une fonction. Pour cela, il faut préciser explicitement grâce au mot-clé global
que la fonction fait référence à la variable globale. Si nous changeons notre
implémentation :
message = "Un message global"
def traiter_message():
global message
message = "Un message local"
print(message)
print(message)
traiter_message()
print(message)
Ce programme produit le résultat suivant et modifie bien le contenu de la variable globale :
Un message global
Un message local
Un message local
Prudence
Le recours à des variables globales est souvent le signe d’une mauvaise conception logicielle et est fortement déconseillé. On se limite généralement à utiliser ce type de variables pour représenter des constantes, c’est-à-dire des valeurs qui ne doivent pas changer pendant l’exécution du programme. Il n’existe pas de méthode directe pour déclarer des constantes en Python, on se contente d’écrire le nom des constantes en majuscules pour signaler notre intention aux autres développeurs :
TAUX_TVA = .2
def calculer_prix_ttc(prix_ht):
tva = round(prix_ht * TAUX_TVA, 2)
return prix_ht + tva
Notez qu’il n’est pas nécessaire d’utiliser le mot-clé global
pour lire et utiliser la valeur d’une variable globale.
Notion de méthode¶
En plus des fonctions, Python connaît la notion de méthode. Une méthode
est une séquence de traitement que l’on effectue sur un type. Une méthode est appelée
pour une valeur, une variable ou un paramètre en utilisant l’opérateur .
.
Par exemple, une chaîne de caractères possède les méthodes upper()
et lower()
permettant de créer une nouvelle chaîne de caractères
en lettres minuscules et respectivement en lettres majuscules :
msg = "Testons les méthodes."
msg_lower = msg.lower()
msg_upper = msg.upper()
print(msg_lower)
print(msg_upper)
msg_upper = "hello".upper()
print(msg_upper)
Une chaîne de caractère possède également la méthode format()
qui permet de réaliser un formatage en utilisant cette chaîne comme modèle.
Les valeurs à insérer sont désignées dans la chaîne par des accolades avec
le numéro de position du paramètre. Si vous voulez appliquer un formatage
particulier aux valeurs, reportez-vous à la documentation complète
.
>>> "Hello {0}".format("David")
'Hello David'
>>> "{0} pèse {1:06.2f}Kg".format("David", 71.33549)
'David pèse 071.34Kg'
Note
Nous verrons plus en détail la notion de méthode lorsque nous aborderons le paradigme de la programmation orientée objet.