Prérequis : bases de Python vues en première (variables, boucles, conditions)
À l’issue de ce chapitre, vous saurez :
- définir et appeler une fonction avec des paramètres positionnels, par mots-clé et par défaut ;
- expliquer la portée locale des variables et le mot-clé
global; - utiliser
*argset**kwargspour un nombre variable de paramètres ; - passer une fonction comme paramètre d’une autre fonction ;
- vérifier les préconditions avec
assertet documenter les fonctions avec des docstrings.
Introduction
Les fonctions sont un moyen efficace de structurer un programme et de l’organiser en modules. Le
choix du nom d’une fonction est important pour la lisibilité du programme. En Python, une fonction
est définie à l’aide du mot-clé def.
def ma_fonction():
print("Les fonctions en Python sont faciles à apprendre")
ma_fonction()
Les fonctions en Python sont faciles à apprendre
À noter que l’appel s’effectue par ma_fonction() au lieu de print(ma_fonction()) car ma_fonction utilise le mot-clé print au lieu de return.
Portée locale des variables
Lorsqu’une nouvelle variable est affectée à l’intérieur du corps de la fonction, elle n’est définie qu’à l’intérieur de la fonction. La variable n’est pas visible en dehors de la fonction. Nous pouvons donc choisir n’importe quel nom lors de la définition des variables sans nous soucier des variables extérieures à la fonction.
Par exemple :
x = 10 # x est une variable globale
y = 10 # y aussi
def une_fonction():
x = 5 # x est une variable locale
global y # Ceci permet de modifier la valeur de la variable globale y
y = 5
print(x)
print(y)
une_fonction()
print(x)
print(y)
10
10
10
5
La variable x ne change pas en dehors de la fonction puisque la portée de x définie à l’intérieur de
la fonction est limitée à la fonction elle-même. Seul le mot-clé global permet de modifier la valeur d’une variable globale.
À ce sujet, voir cette vidéo :
Type de paramètres
Les paramètres, sont utilisés pour transmettre des informations dans une fonction.
Soit la fonction fraction suivante :
def fraction(numerateur, denominateur):
print(f"{numerateur}/{denominateur}")
Il existe plusieurs façons de passer les paramètres :
Paramètres positionnels
Dans la fonction fraction, les paramètres numerateur et denominateur sont appelés paramètres
positionnels (en anglais positional arguments). Il est strictement obligatoire de les préciser lors
de l’appel de la fonction. De plus, il est nécessaire de respecter le même ordre lors de l’appel que
dans la définition de la fonction. Dans l’exemple ci-dessous, 10 correspond à numerateur et 4
correspond à denominateur.
fraction(10, 4)
fraction(*(10, 4))
fraction(*[10, 4])
10/4
10/4
10/4
Paramètres par mots-clé
Un paramètre défini avec une syntaxe def fonction(param=val): est appelé paramètre par mot-clé (en anglais
keyword argument). Le passage d’un tel paramètre lors de l’appel de la fonction est facultatif. Ce
type de paramètre ne doit pas être confondu avec les paramètres positionnels présentés ci-dessus, dont
la syntaxe est def fonction(param):.
fraction(numerateur=10, denominateur=4)
fraction(**{'numerateur': 10, 'denominateur': 4})
10/4
10/4
Paramètres par défaut
Il est possible de préciser des valeurs par défaut pour certains paramètres. Comme leur nom l’indique, ces valeurs seront utilisées par défaut lors d’un appel à la fonction si aucune valeur effective (si aucun paramètre) n’est passée à la place.
Utiliser des valeurs par défaut pour les paramètres de fonctions permet donc aux utilisateurs d’appeler cette fonction en omettant de passer les paramètres possédant des valeurs par défaut.
def presentation(prenom, age=15, ville="Lyon"):
print(
f"Je m'appelle {prenom}, j'ai au moins {age} ans et j'habite à {ville}."
)
presentation("Gaudric")
presentation("Faustin", 19)
presentation("Justine", 21, "Paris")
presentation("Audrey", ville="Toulouse")
presentation(age=20, ville="Strasbourg", prenom="Augustin")
Je m'appelle Gaudric, j'ai au moins 15 ans et j'habite à Lyon.
Je m'appelle Faustin, j'ai au moins 19 ans et j'habite à Lyon.
Je m'appelle Justine, j'ai au moins 21 ans et j'habite à Paris.
Je m'appelle Audrey, j'ai au moins 15 ans et j'habite à Toulouse.
Je m'appelle Augustin, j'ai au moins 20 ans et j'habite à Strasbourg.
Nombre variable de paramètres
Complément hors programme. Les syntaxes *args et **kwargs ne sont pas exigibles au baccalauréat, mais on les rencontre dans la documentation des bibliothèques.
La syntaxe *args (remplacez args par ce que vous voulez) permet d’indiquer lors de la définition
d’une fonction qu’elle peut accepter un nombre variable de paramètres. Ces paramètres sont
intégrés dans un tuple. On va pouvoir préciser zéro, un ou plusieurs paramètres classiques dans la
définition de la fonction avant la partie variable.
def aire_rectangle(*args):
if len(args) == 2:
return args[0] * args[1]
else:
print("Merci de stipuler deux paramètres")
print(aire_rectangle(3, 8))
24
De façon alternative, la syntaxe **kwargs (on peut remplacer kwargs par ce que l’on veut) permet
également d’indiquer que la fonction peut recevoir un nombre variable de paramètres mais cette
fois-ci les paramètres devront être passés sous la forme d’un dictionnaire Python.
def aire_rectangle2(**kwargs):
if len(kwargs) == 2:
result = 1
for key, value in kwargs.items():
result *= value
return result
else:
print("Merci de stipuler deux paramètres")
print(aire_rectangle2(cote1=4, cote2=8))
32
Les syntaxes *args et **kwargs peuvent être utilisées pour réaliser les opérations inverse de celles
présentés ci-dessus, à savoir séparer des données composites pour passer les valeurs ou éléments de
ces données un à un en paramètres des fonctions. On, utilisera la syntaxe *args pour séparer les
paramètres présents dans une liste ou un tuple et la syntaxe **kwargs pour séparer les paramètres
présents dans un dictionnaire et fournir des paramètres nommés à une fonction.
def somme(a, b, c):
s = a + b + c
print(s)
ma_liste = [1, 2, 3]
# somme(ma_liste) # Erreur car la somme attend trois paramètres
somme(*ma_liste)
mon_dico = {'a': 1, 'b': 2, 'c': 3}
somme(**mon_dico)
6
6
Fonctions comme paramètres
On peut également passer une fonction comme paramètre. Par exemple, on peut passer la fonction
intégrée len() ou une fonction définie par l’utilisateur voyelle_presente() comme paramètre à une
autre fonction :
phrase = ['Les', 'fonctions', 'Python', 'sont', 'formidables']
def appliquer_fonction(prop):
return [prop(mot) for mot in phrase]
print(appliquer_fonction(len))
def voyelle_presente(mot):
for x in mot:
if x in 'aeiouy':
return True
return False
print(appliquer_fonction(voyelle_presente))
[True, True, True, True, True]
Vérification du type des paramètres
Python n’oblige pas à spécifier le type des paramètres d’une fonction. Il est donc nécessaire de vérifier le type de variable d’entrée avant d’exécuter la fonction.
def est_une_voyelle(lettre):
if lettre in 'aeiouy':
return True
return False
print(est_une_voyelle("poire"))
False
Pour éviter l’exécution et générer une erreur, on peut utiliser la fonction assert comme ceci.
def est_une_voyelle(lettre):
assert (isinstance(lettre, str)), "La lettre doit être un caractère"
assert (len(lettre) == 1), "La longueur de la lettre doit être de un !"
if lettre in 'aeiouy':
return True
return False
print(est_une_voyelle("f"))
print(est_une_voyelle("poire"))
False
AssertionError: La longueur de la lettre doit être de un !
Si l’instruction assert échoue, elle produit une erreur, affiche le mesage correspondant et la
fonction arrête l’exécution.
Documentation
Il est recommandé de documenter les fonctions : pour cela on utilise une docstring.
def est_une_voyelle(lettre):
'''Prend en paramètre une chaîne de caractères de longueur un et retourne True si c'est une voyelle et False si ce n'est pas la cas'''
assert (isinstance(lettre, str)), "La lettre doit être un caractère"
assert (len(lettre) == 1), "La longueur de la lettre doit être de un!"
if lettre in 'aeiouy':
return True
return False
La docstring de n’importe quelle fonction peut être affichée en exécutant la fonction help.
help(est_une_voyelle)
Help on function est_une_voyelle in module __main__:
est_une_voyelle(lettre)
Prend en paramètre une chaîne de caractères de longueur un et retourne True si c'est une voyelle et False si ce n'est pas la cas
Vérifiez votre compréhension
- Quelle est la différence entre
returnetprintdans une fonction ?Réponse
returnrenvoie une valeur que le programme peut utiliser (stocker dans une variable, passer à une autre fonction, etc.) et met fin à l'exécution de la fonction.printaffiche simplement un texte à l'écran sans renvoyer de valeur exploitable (la fonction renvoie alorsNone). - Que se passe-t-il si on modifie une variable
xà l’intérieur d’une fonction sans utiliserglobal?Réponse
Python crée une variable locale du même nom, qui n'existe que dans la fonction. La variable globalexn'est pas modifiée. C'est la portée locale : les variables définies dans une fonction ne sont pas visibles à l'extérieur. - Pourquoi utilise-t-on
assertpour vérifier les paramètres d’une fonction ?Réponse
Les assertions permettent de vérifier les préconditions : si un paramètre ne respecte pas les hypothèses de la fonction (mauvais type, valeur hors domaine…), le programme s'arrête immédiatement avec un message d'erreur explicite, au lieu de produire un résultat faux ou une erreur difficile à comprendre plus tard.
- Une fonction structure le code en unités réutilisables ; elle est définie avec
defet renvoie une valeur avecreturn. - Les variables locales n’existent que dans la fonction ; seul
globalpermet de modifier une variable extérieure (à éviter dans la mesure du possible). - Les paramètres peuvent être positionnels, par mots-clé ou par défaut ;
*argset**kwargspermettent un nombre variable de paramètres. - Les assertions vérifient les préconditions ; les docstrings documentent le rôle, les paramètres et le comportement d’une fonction (consultables avec
help()). - Les fonctions peuvent être passées comme paramètres d’autres fonctions, ce qui est à la base de la programmation fonctionnelle .
Elle peut également être affichée à l’aide de l’attribut __doc__.
print(est_une_voyelle.__doc__)
Prend en paramètre une chaîne de caractères de longueur un et retourne True si c'est une voyelle et False si ce n'est pas la cas