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'instructionreturn 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 testn%3 == 0
) qui entre en jeu. La lignereturn 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
etn%3 == 0
sont égaux à False et les instructionsreturn True
ne sont donc pas exécutées: la fonction ne termine donc pas avant la dernière ligne. L'instructionreturn 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.
- Corrigez l'erreur.
- 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)