Aller au contenu

Valeur renvoyée par une fonction

Valeur renvoyée

La valeur renvoyée par une fonction (on parle parfois de sortie en opposition aux paramètres qui sont les entrées) est, en langage python, ce qui suit le mot clef return.

Un point important à retenir est le fait qu'une ligne return ... termine l'exécution de la fonction.

Exemple

On considère le code python suivant:

def f(n):
    """
    n -- entier naturel
    renvoie True si n est multiple de 3 ou si n est multiple de 2,
    renvoie False sinon.
    """
    if n%2 == 0: 
        return True
    if n%3 == 0:
        return True
    return False

Faîtes quelques tests et cherchez à comprendre le déroulement. Il faut comprendre notamment que la valeur renvoyée n'est pas toujours False bien que le code se termine par return False sans condition.

Solution
  • Avec l'argument n=4, le test n%2 == 0 est égal à True. L'instruction return True qui suit est donc exécutée: la valeur renvoyée est donc True et l'exécution du corps de la fonction est terminée (les lignes suivantes ne sont pas exécutées dans ce cas, et en particulier la dernière ligne).
  • Avec l'argument n=9, le déroulement est analogue mais c'est la seconde instruction return True (après le test n%3 == 0) qui entre en jeu. La ligne return False, à nouveau, n'est pas exécutée.
  • Dans le cas d'un entier ni pair, ni multiple de 3 (par exemple l'argument 7), les deux tests n%2 == 0 et n%3 == 0 sont égaux à False et les instructions return True ne sont donc pas exécutées: la fonction ne termine donc pas avant la dernière ligne. L'instruction return False est donc exécutée et la fonction renvoie False comme attendu.
Remarque

Le code de cette fonction est écrit de façon plus efficace comme suit:

def f(n):
    """
    n -- entier naturel
    renvoie True si n est multiple de 3 ou si n est multiple de 2,
    renvoie False sinon.
    """
    return n%2 == 0 or n%3 == 0

Fonction ne renvoyant pas de valeur

Certaines fonctions ne renvoient pas de valeur (on parle alors parfois de procédure plutôt que de fonction). Cela doit apparaître dans la chaîne de documentation.

Par exemple, une fonction dont le rôle est de faire un affichage:

def nomFonction(paramètre1, paramètre2, paramètre3):
    """
    paramètre1 -- type du paramètre, précondition éventuelle
    paramètre2 -- type du paramètre, précondition éventuelle
    paramètre3 -- type du paramètre, précondition éventuelle

    affiche...(descriptif de l'affichage, lien avec les paramètres)
    """

Le verbe utilisé n'est donc pas "renvoyer" dans ce cas, ce qui permet de savoir que l'on est en présence d'une procédure (et en général en présence d'une fonction avec effet de bord).

fonction à effet de bord

Le début d'un article wikipedia:

En informatique, une fonction est dite à effet de bord (traduction mot à mot de l'anglais side effect, dont le sens est plus proche d'effet secondaire) si elle modifie un état en dehors de son environnement local, c'est-à-dire a une interaction observable avec le monde extérieur autre que retourner une valeur. Par exemple, les fonctions qui modifient une variable non locale ou un argument mutable passé par référence, les fonctions qui effectuent des opérations d'entrées-sorties ou les fonctions appelant d'autres fonctions à effet de bord. Souvent, ces effets compliquent la lisibilité du comportement des programmes et/ou nuisent à la réutilisabilité des fonctions et procédures.

Important

En Python, on repère rapidement qu'une fonction ne renvoie pas de valeur en constatant que la fonction ne contient pas d'instruction return.

En langage Python, une fonction ne contenant pas de return renvoie en fait toujours par défaut l'objet None (objet spécial du langage que vous pouvez penser pour le moment comme désignant le "vide", le "rien").

Exercice

Il y a une erreur dans la chaîne de documentation de la fonction suivante.

  1. Corrigez l'erreur.
  2. Donnez un nom plus approprié à la fonction.
def f(x):
    """
    x -- nombre (int ou float)
    renvoie le cube de x
    """
    y = x*x*x
    print(y)
Correction de l'erreur dans le docstring

La fonction ne renvoie aucune valeur. Elle se contente d'afficher une valeur.

Le docstring doit donc être corrigé afin de clairement signifier que cette fonction est une fonction d'affichage.

def f(x):
    """
    x -- nombre (int ou float)
    affiche le cube de x 
    ne renvoie rien
    """
    y = x*x*x
    print(y)

Remarque: en python, lorsqu'une fonction ne comporte pas d'instruction return, elle renvoie en fait l'objet None.

Un nom plus approprié

Un nom approprié pour une fonction est un nom qui explicite son rôle. Ici par exemple, un nom tel que cube ne serait pas approprié, ce nom cube serait en effet à réserver à une fonction de calcul du cube, c'est à dire à une fonction qui renvoie le cube de son entrée, telle que la suivante:

def cube(x):
    """
    x -- nombre (int ou float)
    renvoie le cube de x        
    """
    y = x*x*x
    return y

Un nom approprié pour la fonction de l'énoncé:

def afficheCube(x):
    """
    x -- nombre (int ou float)
    affiche le cube de x 
    ne renvoie rien
    """
    y = x*x*x
    print(y)

En effet, avec un paramètre effectif, par exemple 4, cube(4) est la valeur du cube de 4 et peut être utilisée telle quelle dans un autre calcul, tandis que afficheCube(4) n'est pas le cube de 4. afficheCube(4) a pour valeur None (et a pour effet d'afficher le cube de 4 sur la sortie standard, mais ce n'est qu'un affichage qui ne peut pas être utilisé dans un calcul).

Exercice

Question 1

On définit les deux fonctions suivantes:

def f(x):
    return x**2


def g(x):
    print(x**2)

Quels seront les résultats des instructions ci-dessous ?

>>> f(5) + 2
>>> g(5) + 2
Solution
>>> f(5) + 2
27
>>> g(5) + 2
Error 
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

La fonction g ne renvoie rien (ou plutôt renvoie l'objet None) puisque le corps de cette fonction ne comporte pas d'instruction return.

Rappelons, une fois de plus, que l'instruction print est une instruction d'affichage: l'effet de la fonction g est uniquement de produire un affichage de texte (sur la sortie standard) et on ne fait pas des calculs avec un affichage (d'où l'obtention d'une erreur pour g(5) + 2). g(5) a pour valeur None (objet spécifique Python) mais f(5) est bien égal à 25.

Question 2

Donner pour les deux fonctions précédentes une chaîne de documentation adéquate et renommer ces deux fonctions de façon plus appropriée.

Solution
def carre(x):
    """
    x --  nombre (entier ou flottant)
    renvoie le carré de x
    """
    return x**2


def affichage_carre(x):
    """
    x -- nombre (entier ou flottant)
    affiche le carré de x
    (ne renvoie rien)
    """
    print(x**2)