Ce document est extrait de notre cours de python

Définir et appeler une fonction

Principe

Une fonction est une boîte étanche avec une étiquette dessus (son nom), et qui contient des instructions. On peut appeler cette boîte pour exécuter les instructions qu’elle contient.

Pour créer une fonction (on dit la définir), on utilise le mot-clé def, suivi du nom de la fonction, puis de () et d’un :. Le code contenu dans la fonction (son corps) est le code indenté en dessous.

# définition d'une fonction appelée hello
def hello():
    print("Bonjour ...")
    print("        ... le monde")

# ici, on est en dehors de la fonction

Définir une fonction n’exécute pas son code : ce programme n’affiche rien.

Nom d’une fonction

Le nom d’une fonction suit les mêmes règles que le nom d’une variable :

Par convention, on l’écrit en minuscules, sans accents, avec des _ à la place des espaces : calcule_moyenne, affiche_menu.

Appeler une fonction

Pour exécuter le code contenu dans la fonction (= appeler la fonction), on écrit son nom, suivi de parenthèses.

hello()

Affichage :

Bonjour ...
        ... le monde

Lors de l’appel, le programme exécute les instructions de la fonction, puis reprend là où il en était :

print(".................")
hello()
print("=================")

Affichage :

.................
Bonjour ...
        ... le monde
=================

Une fonction peut appeler une autre fonction

def presentation():
    print("Attention je vais parler :")
    hello()
    print("C'est tout pour moi, merci.")

# Appel de la fonction presentation
print(".....................")
presentation()
print("=====================")

Affichage :

.....................
Attention je vais parler :
Bonjour ...
        ... le monde
C'est tout pour moi, merci.
=====================

Variables locales

Une variable créée dans une fonction est locale

Une variable créée dans une fonction est une variable locale : elle n’existe que pendant l’exécution de la fonction, et on ne peut pas l’utiliser en dehors.

def printx():
    x = "coucou"
    print(x)

printx()
print(x)

Affichage :

coucou
NameError: name 'x' is not defined

L’appel printx() affiche coucou. Le print(x) placé en dehors de la fonction provoque une erreur : la variable x n’existe pas en dehors de printx.

Renvoyer une valeur : return

Le mot-clé return

Une fonction peut renvoyer un résultat avec le mot-clé return. L’appel de la fonction est alors remplacé par la valeur renvoyée : on peut la ranger dans une variable, l’afficher, ou l’utiliser dans un calcul.

def monnombre():
    print("Je vous renvoie un nombre")
    return 42

x = monnombre()
print(x)

Affichage :

Je vous renvoie un nombre
42

return termine la fonction

Le return termine directement l’exécution de la fonction : les instructions placées après ne sont pas exécutées.

def monnombre():
    print("Je vous renvoie deux nombres")
    return 42
    return 12

x = monnombre()
print(x)

Affichage :

Je vous renvoie deux nombres
42

La ligne return 12 n’est jamais exécutée.

Afficher ou renvoyer ?

print affiche une valeur à l’écran, mais le programme ne peut pas la réutiliser. return renvoie la valeur au programme, sans rien afficher.

Une fonction qui n’a pas de return renvoie la valeur spéciale None (« rien »).

def double_affiche(n):
    print(n * 2)

def double_renvoie(n):
    return n * 2

a = double_affiche(5)    # affiche 10
b = double_renvoie(5)    # n'affiche rien
print(a, b)

Affichage :

10
None 10

Paramètres et arguments

Paramètres

Une fonction peut recevoir des valeurs en entrée. On écrit entre les parenthèses de la définition les paramètres de la fonction : chaque paramètre a un nom, et se comporte comme une variable locale qui reçoit sa valeur au moment de l’appel. Les valeurs données lors de l’appel s’appellent les arguments.

def commentaire_age(age):
    if age < 18:
        print("Trop jeune")
    elif age < 70:
        print("Bonjour")
    else:
        print("Trop vieux")

commentaire_age(22)

Affichage :

Bonjour

Ici, age est le paramètre et 22 l’argument : pendant cet appel, age vaut 22.

Plusieurs paramètres

def affine(x, a, b):
    return a*x + b

print(affine(1, 4, 5))

Affichage :

9

Les arguments sont associés aux paramètres dans l’ordre : x vaut 1, a vaut 4 et b vaut 5.

Arguments par position ou par nom

On peut donner les arguments d’une fonction par position (comme au-dessus). On peut aussi donner ces arguments par nom :

print(affine(x=1, a=4, b=5))
# Avantage : on peut les donner dans le désordre
print(affine(a=4, b=5, x=1))

Affichage :

9
9

On peut aussi mélanger les deux. Seule contrainte : on donne d’abord les arguments par position, puis ceux par nom.

print(affine(1, b=5, a=4))

Affichage :

9

Dans le cas contraire, Python signale une erreur :

affine(a=9, 1)
SyntaxError: positional argument follows keyword argument

Valeurs par défaut

On peut rendre certains paramètres optionnels en leur donnant une valeur par défaut. Les paramètres qui ont une valeur par défaut se placent après ceux qui n’en ont pas.

def affine(x, a, b=13):  # si b n'est pas fourni, il vaut 13
    return a*x + b

# Par position
print(affine(1, 4))
# Par nom
print(affine(x=1, a=4))
# En mélangeant
print(affine(1, a=4))

Affichage :

17
17
17

Il faut lire les erreurs

Si on oublie un argument qui n’a pas de valeur par défaut, Python signale une erreur :

affine(x=3)
TypeError: affine() missing 1 required positional argument: 'a'

Le message indique qu’il manque l’argument a lors de l’appel de affine.

Exemples

La machine à café

La chaîne de caractères entre triples guillemets """ placée juste après la ligne def s’appelle la docstring : elle explique ce que fait la fonction et à quoi servent ses paramètres. On peut l’afficher avec help(cafe).

def cafe(source=0, force=0, sucre=0):
    """Affichage de la machine à café :

    affiche la chaîne de caractères correspondant au café choisi

    Arguments :
    - source: 0 = grains, 1 = soluble
    - force: 0 = court, 1 = long, 2 = extra long
    - sucre: 0 = sans, 1 = sucré, 2 = très sucré
    """
    if source == 0:
        print("Café en grains", end=" ")
    else:
        print("Café soluble", end=" ")

    if force == 0:
        print("court", end=" ")
    elif force == 1:
        print("long", end=" ")
    else:
        print("extra long", end=" ")

    if sucre == 0:
        print("sans sucre")
    elif sucre == 1:
        print("sucré")
    else:
        print("très sucré")

cafe(source=1, force=2, sucre=2)
cafe()
cafe(1, 1, 1)

Affichage :

Café soluble extra long très sucré
Café en grains court sans sucre
Café soluble long sucré

Plusieurs return

def code(secret):
    if secret == "supercode":
        return "entrez"
    else:
        return "interdit"

print(code("supercode"))

Affichage :

entrez

On peut aussi écrire :

def code(secret):
    if secret == "supercode":
        return "entrez"
    return "interdit"

Les deux versions sont équivalentes : si le code est bon, le premier return termine la fonction, et la dernière ligne n’est pas exécutée.

Retour sur l’étanchéité des fonctions

Une étanchéité relative

L’étanchéité des fonctions est « relative »…

Une variable définie en dehors de toute fonction s’appelle une variable globale.

Lire une variable globale

Une fonction peut lire la valeur d’une variable globale :

a = 15
def fonction(b):
    print(a*b)  # La valeur de a est lue en dehors de la fonction

fonction(5)

Affichage :

75

Une variable locale du même nom

Si on affecte une valeur à a dans la fonction, a devient une variable locale dans toute la fonction : on ne peut plus lire la variable globale a.

a = 15
def fonction(b):
    print(a*b)  # Ne fonctionne plus : a est une variable locale de la fonction
    a = 1
    return a

fonction(5)
UnboundLocalError: cannot access local variable 'a' where it is not associated with a value

Au moment du print, la variable locale a n’a pas encore de valeur.

Modifier une variable globale

Pour la même raison, une fonction ne peut pas modifier directement une variable globale :

a = 15
def fonction():
    a = a + 1

fonction()
print(a)
UnboundLocalError: cannot access local variable 'a' where it is not associated with a value

Le mot-clé global permet d’indiquer que a est la variable globale :

a = 15
def fonction():
    global a
    a = a + 1

fonction()
print(a)

Affichage :

16

À retenir

Le mieux, c’est de toujours conserver l’étanchéité parfaite des fonctions :