Aller au contenu

Fonctions

Définition et appel d'une fonction

Une fonction accepte un nombre fixé d'arguments. Une fonction python renvoie toujours quelque chose. Lors que le mot-clé return n'est pas utilisé, la valeur de retour est None par défaut.

Il est obligatoire de préciser la docstring de la fonction, sur le schéma suivant :

  • la première ligne est la signature de la fonction. Elle indique le type des paramètres d'entrée, ainsi que le type des valeurs renvoyées par la fonction.
  • Les lignes suivantes indiquent quelle opération réalise la fonction. On peut éventuellement y préciser à titre indicatif les conditions portant sur les paramètres d'entrée, les propriétés vérifiées par la valeur de retour…
1
2
3
4
5
6
7
def bonjour(nom, prenom):
    """ str -> None
    Affiche un message de bienvenue """
    print(f"Bonjour à toi, {prenom} {nom} !")

retour = bonjour("Asimov", "Isaac")
print(retour)
Bonjour à toi, Isaac Asimov !
None
1
2
3
4
5
6
7
8
def ajoute(x, y):
    """ int, int -> int
    x > 0, y > 0
    Ajoute les nombres x et y """
    return x + y

retour = ajoute(1, 2)
print(retour)
3

Arguments optionnels

Il est possible de spécifier une valeur par défaut pour certains arguments de la fonction. Si l'utilisateur appelle la fonction sans préciser la valeur de l'argument, la valeur par défaut sera utilisée. Les arguments optionnels sont indiqués après les arguments de la fonction.

1
2
3
4
def signature(nom, prenom, politesse="Sincèrement"):
    """ str, str, (str) -> None
    Affiche une formule de politesse pour finir une lettre """
    print(f"{politesse}, {prenom} {nom}.")
1
2
signature("Octavia", "Butler")
signature("Octavia", "Butler", politesse="Cordialement")
Sincèrement, Butler Octavia.
Cordialement, Butler Octavia.

Du danger des objets mutables

Attention. Il ne faut jamais utiliser d'objet mutable comme valeur par défaut d'un argument.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def ajoute_x(x, l=[]):
    """ int, [int] -> [int]
    Ajoute x à la liste l (par défaut la liste vide). """
    l.append(x)
    return l

liste_1 = [1, 2]    
print(ajoute_x(3, l=liste_1))
print(ajoute_x(1))
print(ajoute_x(2)) # la _même_ liste l est utilisée pour tous les appels
[1, 2, 3]
[1]
[1, 2]

Solution. On utilise un argument par défaut égal à None et on lui affecte la valeur souhaitée s'il n'est pas passé en argument à la fonction.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def ajoute_x(x, l=None):
    """ int, [int] -> [int]
    Ajoute x à la liste l (par défaut la liste vide). """
    if not l:
        l = []
    l.append(x)
    return l

liste_1 = [1, 2]    
print(ajoute_x(3, l=liste_1))
print(ajoute_x(1))
print(ajoute_x(2)) # à chaque appel on instancie une nouvelle variable locale l 
[1, 2, 3]
[1]
[2]

Valeur(s) de retour

Une fonction peut renvoyer une ou plusieurs valeurs à l'aide du mot-clé return. Dans le cas où une fonction renvoie plusieurs valeurs, on peut les affecter directement à des variables lors de son appel.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def maximum(liste):
    """ [int] -> int, int
    len(liste) > 0
    Renvoie l'indice et la valeur d'un maximum de liste """
    i_maxi = 0
    maxi = liste[0]
    for i in range(len(liste)):
        if liste[i] > maxi:
            i_maxi, maxi = i, liste[i]
    return  i_maxi, maxi      
1
2
i, m = maximum([-2, 5, 2, -8, 9, 5, 4, 3, 0, 9])
print(f"Un maximum est {m}, à l'indice {i}")
Un maximum est 9, à l'indice 4

Variables locales, variables globales

Toute variable définie dans le corps d'une fonction est locale à celle-ci. Les autres variables sont des variables globales.

1
2
3
4
5
6
x = 1 # x est globale
def f(a):
    """ int -> int """
    y = a + 1 # y est locale
    x = 2*y # version locale de x, masque la variable globale dans la fonction
    return x + y
1
2
3
4
print(x) # x est une variable globale
print(f(5))
print(x) # version globale de x 
print(y) # y est une variable locale à f
1
18
1
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [1764], in <cell line: 4>()
      2 print(f(5))
      3 print(x) # version globale de x 
----> 4 print(y)

NameError: name 'y' is not defined

Fonction anonyme et mot-clé lambda

On peut également définir une fonction à l'aide du mot-clé lambda.

1
2
3
4
5
6
def applique_fonction(f, tab):
    """ (int -> int), [int] -> [int]
    Applique la fonction f à tous les éléments du tableau """
    for i in range(len(tab)):
        tab[i] = f(tab[i])
    return tab
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def plus_1(x):
    return x + 1
tab = [1, 2, 3]
tab = applique_fonction(plus_1, tab)
print(tab)

plus_2 = lambda x: x + 2 # plus_2 est une fonction
print(plus_2(3)) # on appelle plus_2 normalement
tab = applique_fonction(plus_2, tab)
print(tab)

tab = applique_fonction(lambda x: 2*x, tab)
print(tab)
[2, 3, 4]
5
[4, 5, 6]
[8, 10, 12]