Les fonctions Python
return. Découvre les variables qu’une fonction peut voir et modifier, décris tes fonctions avec des docstrings et décompose un programme en petites fonctions aux noms explicites, que tu construis et testes une par une.DébutantUnité 4 sur 10 de la formation Formation : Python : variables, boucles, fonctions et fichiers
Ce que tu vas apprendre
- Écris une fonction avec
def, exécute-la en l’appelant et suis l’ordre dans lequel Python exécute un programme qui contient des fonctions.- Définir une fonction et l’appelerÉcris l’en-tête et le corps indenté d’une fonction, choisis un nom explicite et exécute la fonction en l’appelant avec des parenthèses.
- Suivre le flot d’exécutionSuis l’ordre dans lequel Python exécute les instructions lorsque des fonctions en appellent d’autres, et prévois la sortie d’un programme à partir de cet ordre.
- Définir une fonction et l’appeler
- Utilise des paramètres et des arguments pour fournir à une fonction les valeurs sur lesquelles elle travaille, en les associant par position, par nom ou au moyen de valeurs par défaut.
- Utiliser des paramètres et des arguments positionnelsAjoute des paramètres à l’en-tête d’une fonction, transmets les arguments correspondants dans un appel et lis les erreurs produites par un nombre incorrect d’arguments.
- Appeler des fonctions avec des arguments nommésTransmets des arguments par nom de paramètre, combine les arguments positionnels et nommés dans le bon ordre et corrige les erreurs dues à des combinaisons incorrectes.
- Donner des valeurs par défaut aux paramètresRends des paramètres facultatifs avec des valeurs par défaut, place correctement les paramètres obligatoires et facultatifs, et sache quand une valeur par défaut est créée.
- Utiliser des paramètres et des arguments positionnels
- Utilise
returnpour renvoyer une valeur au code qui a appelé une fonction, distingue le renvoi de l’affichage et écris des fonctions dont les résultats peuvent être stockés, testés et combinés.- Renvoyer une valeur et l’utiliserTermine une fonction avec
return, utilise la valeur renvoyée dans des variables et des expressions, et comprends pourquoi renvoyer une valeur est différent de l’afficher. - Renvoyer depuis différents chemins et combiner les résultatsÉcris des fonctions avec plusieurs instructions return, renvoie True ou False, effectue un retour anticipé depuis une boucle, renvoie deux valeurs et transmets le résultat d’une fonction à une autre.
- Renvoyer une valeur et l’utiliser
- Prévois les variables qu’une fonction peut voir et modifier, fais entrer et sortir les données par des paramètres et des valeurs de retour, et utilise
globalseulement lorsque c’est vraiment nécessaire.- Manipuler des variables locales et des paramètresExplique pourquoi les variables créées dans une fonction n’existent que pendant son appel, comment Python trouve un nom et pourquoi modifier un paramètre ne modifie pas la variable de l’appelant.
- Utiliser les variables globales avec prudenceLis les valeurs globales sans risque, comprends l’erreur causée par une affectation à un nom global, utilise correctement l’instruction
globalet privilégie les paramètres et les valeurs de retour.
- Manipuler des variables locales et des paramètres
- Décris des fonctions avec des docstrings, décompose un problème en petites fonctions aux noms explicites et construis et vérifie un programme fonction par fonction.
- Documenter des fonctions avec des docstringsÉcris des docstrings d’une ligne et multilignes qui suivent les conventions courantes, et lis-les avec
help(). - Décomposer un problème en fonctionsDécompose une tâche en étapes, transforme chaque étape en fonction avec des entrées et des sorties explicites, et organise le programme autour d’une fonction
main. - Construire et vérifier un programme fonction par fonctionDéveloppe un programme par petites étapes, teste chaque fonction avec des entrées dont tu connais les résultats et utilise les traces d’appels et des affichages temporaires pour trouver les bugs dans les fonctions.
- Documenter des fonctions avec des docstrings
Fonctions Python : cours
1Définir et appeler tes propres fonctions
Une fonction donne un nom à une partie utile du code, afin que tu puisses l’exécuter chaque fois que cette tâche est nécessaire. Écrire la définition et effectuer un appel sont deux actions distinctes, et cette différence explique pourquoi certains programmes se terminent sans rien afficher. Tu vas écrire des définitions correctement indentées, choisir des noms lisibles et suivre l’exécution lorsqu’une fonction en appelle une autre, puis revient à son appelant.
1.1 Définir une fonction et l’appeler
Une fonction est un bloc de code nommé qui accomplit une tâche. Les fonctions natives comme print() et input() te fournissent déjà des tâches utiles à appeler ; def te permet de créer les tiennes. Un bon nom transforme plusieurs lignes de travail en un appel qui indique ce que tu veux faire.
Écrire l’en-tête et le corps
def greet():
print("Hello!")
print("Welcome to Python.")
greet()
greet()
L’en-tête commence par def, puis viennent le nom, les parenthèses et les deux-points. Les lignes indentées forment le corps. Utilise quatre espaces pour chaque niveau d’indentation. Les lignes greet() non indentées sont hors de la fonction : ce sont donc des appels dans le programme principal.
Lorsque Python atteint la définition, il crée la fonction et lui donne le nom greet. Il n’affiche encore aucun des deux messages. Le premier appel commence à la première ligne du corps et affiche « Hello! » suivi de « Welcome to Python. ». Le second appel reprend le corps et affiche les deux mêmes lignes. Il y a quatre lignes de sortie en tout.
Un nom et un appel sont différents
Les parenthèses dans greet() en font un appel, même si cette fonction n’a besoin d’aucune entrée. Une ligne contenant seulement greet désigne la fonction et n’exécute rien. print(greet) affiche une description de l’objet fonction, avec une adresse mémoire ; il n’exécute pas le message de bienvenue.
Python doit avoir exécuté une définition avant qu’un appel utilise son nom. Si un fichier commence par greet() et définit greet ensuite, la première ligne déclenche NameError: name 'greet' is not defined. Place la définition avant l’appel au premier niveau du fichier.
Choisir des noms qui expliquent la tâche
Utilise des mots en minuscules reliés par des traits de soulignement, comme print_receipt ou convert_to_miles. Les noms peuvent contenir des lettres, des chiffres et des traits de soulignement, mais ne peuvent pas commencer par un chiffre ni être un mot réservé comme return. Les noms sont sensibles à la casse : greet et Greet sont des noms différents.
Garde les noms natifs disponibles. Après input = "yes", le nom input désigne du texte : input("Name? ") déclenche donc TypeError: 'str' object is not callable. Nommer la variable answer permet de garder la fonction native accessible.
Corriger d’abord la structure
L’absence des deux-points dans l’en-tête produit SyntaxError: expected ':'. Un corps vide ou non indenté produit une IndentationError. Une fonction en cours de conception a tout de même besoin d’une instruction ; pass est une instruction provisoire qui ne fait rien :
def print_receipt():
pass
print_receipt()
Ce programme s’exécute sans rien afficher. L’appel atteint pass puis la fin du corps. Remplace l’instruction provisoire par la tâche réelle lorsque tu es prêt à l’implémenter. Si une ligne devait appartenir au corps mais s’exécute au mauvais moment, vérifie son indentation avant de modifier l’appel.
Points clés
- Utilise
def name():et un corps indenté pour définir une fonction. - Une définition crée la fonction ; les parenthèses constituent un appel qui l’exécute.
- Exécute la définition d’une fonction avant d’effectuer un appel qui a besoin de son nom.
- Choisis des noms descriptifs en minuscules avec des traits de soulignement et évite les noms natifs.
- Utilise
passlorsqu’une fonction en cours de conception a besoin d’un corps provisoire valide.
1.2 Suivre le flot d’exécution
Un programme avec des fonctions n’exécute pas chaque corps dans l’ordre où il apparaît sur la page. Un appel modifie le flot d’exécution : Python entre dans la fonction appelée, termine son travail, puis reprend l’exécution dans l’appelant juste après cet appel.
Suivre un appel dans un autre appel
def line():
print("----------")
def banner():
line()
print(" REPORT")
line()
print("Start")
banner()
print("End")
Python définit d’abord line et banner. Aucun des deux corps ne s’exécute. L’instruction suivante affiche « Start ». L’appel à banner() entre dans son corps, dont la première instruction appelle line().
Python entre alors dans line, affiche « ---------- » et atteint sa fin. Il revient à l’instruction suivante dans banner, qui affiche « REPORT ». Le second appel à line() affiche une autre ligne de tirets. Enfin, banner se termine : le programme principal reprend et affiche « End ».
La sortie est :
Start
----------
REPORT
----------
End
Suivre les appels non terminés
Pendant que line s’exécute, banner attend qu’elle se termine. Le programme principal attend lui aussi banner. Python enregistre ces appels non terminés dans la pile d’appels. L’appel actif le plus interne se termine en premier, et chaque appelant reprend à son instruction suivante.
Pour suivre l’exécution sur papier, numérote les lignes du programme. Ne note une ligne du corps que lorsque l’exécution l’atteint par un appel. À chaque appel, indique où reprendre. Écris la sortie lorsque son print s’exécute, en conservant les espaces et les sauts de ligne. Cela distingue le parcours dans le code de la sortie produite.
Définir les fonctions auxiliaires avant qu’elles soient nécessaires
La définition d’une fonction auxiliaire peut apparaître sous celle de l’appelant :
def show_report():
draw_line()
print("Ready")
def draw_line():
print("====")
show_report()
Cela fonctionne parce que les deux définitions ont été exécutées avant que l’appel final entre dans show_report. Python cherche draw_line lorsque le corps l’appelle effectivement. Déplacer show_report() au-dessus de def draw_line(): ferait échouer l’appel lorsqu’il essaierait d’utiliser la fonction auxiliaire manquante.
Les appels répétés repartent du début
Un appel dans une boucle entre dans le corps à chaque répétition :
for i in range(3):
line()
Avec la première définition de line, cela affiche la ligne de tirets trois fois. La fonction commence à la première instruction de son corps à chaque appel.
Si un appel échoue, Python affiche une trace d’appels. Sa dernière ligne donne le type et le message de l’erreur. Les entrées d’appel qui la précèdent vont de l’appel non terminé le plus externe jusqu’à la ligne qui a échoué. Lire d’abord la dernière erreur, puis vérifier la ligne la plus interne et son appelant, aide à repérer l’opération qui a échoué et le chemin par lequel ses données lui sont parvenues.
Points clés
- Suis les instructions des corps dans l’ordre des appels, en notant la sortie lorsque chaque
prints’exécute. - La pile d’appels garde la trace des appels non terminés et de l’endroit où reprendre.
- Une fonction auxiliaire peut être définie sous son appelant si sa définition s’exécute avant son appel.
- Lis la dernière erreur d’une trace d’appels, puis examine la ligne qui a échoué et son appelant.
2Transmettre des informations aux fonctions
Les paramètres permettent à une fonction de traiter différentes entrées sans réécrire son corps. L’appelant fournit des arguments et Python associe ces valeurs aux noms des paramètres avant que le corps commence. Tu vas associer les arguments par position et par nom, combiner correctement ces formes et choisir des valeurs par défaut pour les cas courants. Tu verras aussi pourquoi une valeur par défaut est créée lors de l’exécution de la définition et comment cela affecte une liste utilisée comme valeur par défaut.
2.1 Utiliser des paramètres et des arguments positionnels
Une fonction devient réutilisable avec différentes entrées lorsque son en-tête nomme les valeurs dont elle a besoin. Ces noms sont des paramètres. L’appelant fournit des arguments, qui sont les valeurs effectivement utilisées pour un appel donné.
Associer les valeurs aux noms
def rectangle_area(width, height):
print("Area:", width * height)
rectangle_area(4, 2.5)
rectangle_area(3, 7)
Les paramètres sont width et height. Dans le premier appel, les arguments sont 4 et 2.5. Les arguments positionnels sont associés de gauche à droite : width reçoit 4 et height reçoit 2,5. Le corps affiche « Area: 10.0 ». L’appel suivant donne de nouvelles valeurs aux mêmes noms de paramètres et affiche « Area: 21 ».
Chaque paramètre joue le rôle d’une variable pendant cet appel. Tu n’as pas besoin d’affecter des valeurs à width et height au préalable ; l’appel les fournit. Une fonction sans paramètres a quand même besoin de parenthèses vides dans sa définition et dans ses appels.
L’ordre peut changer le sens
def describe_pet(animal, name):
print(name, "is a", animal)
describe_pet("cat", "Milo")
describe_pet("Milo", "cat")
Le premier appel affiche « Milo is a cat ». Le second affiche « cat is a Milo ». Les deux appels sont valides en Python : aucune erreur ne signale donc l’inversion du sens. Lis l’ordre de l’en-tête avant de choisir les arguments positionnels, surtout lorsque plusieurs paramètres acceptent le même type de valeur.
Les arguments peuvent être des expressions
Python évalue chaque expression utilisée comme argument avant que le corps commence. Avec side = 6, l’appel rectangle_area(side, side) transmet deux fois 6 et affiche « Area: 36 ». Le nom de la variable de l’appelant n’a besoin de correspondre à aucun des deux noms de paramètres. L’appel rectangle_area(side + 1, 2) transmet 7 et 2 ; il ne transmet pas le texte « side + 1 ».
Lire une erreur de nombre d’arguments
Chaque paramètre sans valeur par défaut a besoin d’un argument. Avec la fonction d’aire ci-dessus :
| Appel | Problème |
|---|---|
rectangle_area(4) | height manque. |
rectangle_area(4, 2, 1) | Trois arguments ont été fournis pour deux paramètres. |
Le premier déclenche TypeError: rectangle_area() missing 1 required positional argument: 'height'. Le second déclenche TypeError: rectangle_area() takes 2 positional arguments but 3 were given. Vérifie l’en-tête de la fonction indiquée, puis compte comment l’appel renseigne ses paramètres.
Transmettre le type de valeur nécessaire à la tâche
Python n’impose pas un type simplement parce qu’un paramètre s’appelle width. rectangle_area("4", 2) affiche « Area: 44 », car multiplier du texte par un entier répète ce texte. Comme input() renvoie du texte, convertis une saisie numérique avant de la transmettre :
width = float(input("Width: "))
rectangle_area(width, 2)
Ici, float() transforme le texte saisi en nombre avant que la fonction d’aire le reçoive.
Points clés
- Un paramètre est un nom dans l’en-tête ; un argument est une valeur fournie par un appel.
- Les arguments positionnels renseignent les paramètres de gauche à droite.
- Python évalue les expressions des arguments avant l’exécution du corps de la fonction.
- Chaque paramètre obligatoire a besoin d’une valeur ; des arguments manquants ou en trop déclenchent une
TypeError. - Convertis une saisie numérique reçue sous forme de texte avant de la transmettre à un calcul.
2.2 Appeler des fonctions avec des arguments nommés
Un argument nommé indique dans l’appel le paramètre auquel il est destiné. Cela rend l’appel plus facile à lire lorsque plusieurs valeurs pourraient être confondues. Python associe le nom indiqué à celui de l’en-tête au lieu d’utiliser sa position.
Associer par nom
def describe_pet(animal, name):
print(name, "is a", animal)
describe_pet(name="Milo", animal="cat")
describe_pet(animal="cat", name="Milo")
Les deux appels affichent « Milo is a cat ». L’ordre des arguments nommés peut changer, car chaque valeur indique le paramètre qu’elle renseigne. La même idée rend rectangle_area(width=4, height=2.5) lisible sans vérifier quelle dimension vient en premier.
Un nom indiqué dans un argument nommé n’est pas une nouvelle variable dans le code appelant. Dans describe_pet(name="Milo", animal="cat"), name= dirige « Milo » vers le paramètre. Il n’affecte pas « Milo » à une variable appelée name au premier niveau du fichier. Écris les arguments nommés sans espaces autour de =, conformément au style habituel de Python.
Combiner des arguments positionnels et nommés
describe_pet("cat", name="Milo")
Le premier argument renseigne animal par sa position. L’argument nommé renseigne name : chaque paramètre reçoit donc exactement une valeur. Les arguments positionnels doivent venir en premier. L’appel describe_pet(name="Milo", "cat") est rejeté avec SyntaxError: positional argument follows keyword argument.
Pour examiner un appel mixte, renseigne les emplacements positionnels de gauche à droite, puis associe les arguments nommés. Vérifie qu’aucun emplacement n’est renseigné deux fois et qu’aucun emplacement obligatoire ne reste vide.
Corriger les noms en double ou inconnus
| Appel | Diagnostic |
|---|---|
describe_pet("cat", animal="dog") | animal reçoit à la fois « cat » et « dog ». |
describe_pet(animal="cat", nmae="Milo") | L’en-tête n’a aucun paramètre appelé nmae. |
Le doublon déclenche TypeError: describe_pet() got multiple values for argument 'animal'. La faute de frappe déclenche TypeError: describe_pet() got an unexpected keyword argument 'nmae'. Compare les noms caractère par caractère ; les majuscules et les minuscules comptent aussi. Changer l’ordre des arguments ne corrige pas une double affectation à un même paramètre.
Reconnaître les arguments nommés dans les fonctions natives
print("a", "b", "c", sep="-")
print("Loading", end="...")
print("done")
La première ligne affiche « a-b-c ». sep fournit le texte entre les valeurs affichées. Les deux appels suivants produisent « Loading...done » sur une seule ligne : end remplace le saut de ligne habituel après « Loading ».
Certaines fonctions natives acceptent aussi des arguments nommés ; par exemple, round(3.14159, ndigits=2) donne 3,14. Utilise les noms de paramètres documentés pour la fonction que tu appelles. Un mot descriptif que tu inventes n’est pas reconnu simplement parce qu’il semble convenir à la tâche.
Points clés
- Les arguments nommés correspondent aux noms des paramètres : leur ordre peut donc varier.
- Place les arguments positionnels avant les arguments nommés.
- Renseigne chaque paramètre exactement une fois et orthographie chaque nom exactement.
- Dans un appel, un nom dirige une valeur vers un paramètre ; il n’affecte pas de valeur à une variable de l’appelant.
- Pour
print,sepcontrôle les séparateurs etendcontrôle la fin de l’affichage.
2.3 Donner des valeurs par défaut aux paramètres
Une valeur par défaut permet à un appel d’omettre un argument lorsqu’un choix courant convient. Écris la valeur par défaut à côté de son paramètre dans l’en-tête. Fournir un argument remplace la valeur par défaut pour cet appel.
Rendre un paramètre facultatif
def greet(name, greeting="Hello"):
print(greeting + ",", name + "!")
greet("Ana")
greet("Ana", "Welcome")
greet("Ana", greeting="Hi")
La sortie est « Hello, Ana! », « Welcome, Ana! » et « Hi, Ana! ». name est obligatoire car il n’a pas de valeur par défaut. greet() déclenche donc une TypeError, même si l’autre paramètre est facultatif.
Dans ces en-têtes, les paramètres obligatoires précèdent les paramètres avec valeurs par défaut. def greet(greeting="Hello", name): est invalide. Python signale une erreur de syntaxe parce qu’un paramètre sans valeur par défaut suit un paramètre qui en a une. Déplace name avant greeting pour qu’il reste obligatoire.
Modifier un choix facultatif
def order_coffee(size, shots=1, milk="none"):
print(size, "coffee,", shots, "shot(s), milk:", milk)
order_coffee("large", milk="oat")
Cet appel affiche « large coffee, 1 shot(s), milk: oat ». L’argument nommé atteint milk, tandis que shots garde 1. Un appel positionnel order_coffee("medium", 2) modifie shots et laisse milk à « none ». L’association positionnelle ne saute pas un paramètre facultatif pour atteindre le suivant.
Les fonctions natives proposent aussi des valeurs par défaut : un print() ordinaire sépare les valeurs par une espace et termine par un saut de ligne. round(3.7) donne l’entier 4 ; round(3.14159, 2) demande deux décimales et donne 3,14.
Les valeurs par défaut sont créées lors de l’exécution de la définition
rate = 0.05
def price_with_tax(price, tax_rate=rate):
return price * (1 + tax_rate)
rate = 0.08
print(price_with_tax(100))
print(price_with_tax(100, rate))
La valeur par défaut stocke la valeur 0,05 lorsque def s’exécute. Modifier rate ensuite ne change pas cette valeur par défaut stockée. Les appels affichent « 105.0 » et « 108.0 » : seul le second fournit explicitement le nouveau taux.
Éviter de partager une liste par accident
Une liste contient des éléments, et append ajoute un élément à cette même liste. Avec une liste comme valeur par défaut, les appels qui omettent l’argument la partagent tous :
def add_item(item, basket=[]):
basket.append(item)
print(basket)
add_item("apple")
add_item("pear")
Cela affiche ['apple'] puis ['apple', 'pear']. La liste par défaut a été créée une seule fois, et non une fois par appel. Pour créer une nouvelle liste chaque fois que l’argument est omis, utilise None comme signal :
def add_item(item, basket=None):
if basket is None:
basket = []
basket.append(item)
print(basket)
Ces deux appels affichent maintenant ['apple'] et ['pear']. Une liste fournie explicitement est toujours utilisée telle quelle. Décris les paramètres facultatifs et leurs valeurs par défaut dans la docstring afin que les appelants sachent quelles valeurs sont choisies en cas d’omission.
Points clés
- Un argument facultatif omis utilise sa valeur par défaut ; un argument explicite la remplace.
- Place les paramètres obligatoires avant les paramètres avec valeurs par défaut.
- Utilise un argument nommé pour modifier une option ultérieure sans renseigner les emplacements facultatifs précédents.
- Les expressions des valeurs par défaut sont évaluées une seule fois lorsque
defs’exécute. - Une liste mutable utilisée comme valeur par défaut est partagée par les appels qui omettent l’argument.
- Utilise
Noneet crée une liste dans le corps lorsqu’il faut une nouvelle liste chaque fois que l’argument est omis.
3Renvoyer des résultats avec des valeurs de retour
Un calcul devient plus utile lorsque son résultat peut alimenter un autre calcul, une condition ou un affichage. L’instruction return le permet en renvoyant une valeur à l’appelant. Tu vas distinguer le renvoi de l’affichage, suivre le premier return qui s’exécute et vérifier les chemins susceptibles de se terminer sans résultat utile. Tu construiras ensuite des fonctions booléennes, termineras correctement des recherches et combineras les résultats de petites fonctions.
3.1 Renvoyer une valeur et l’utiliser
Une fonction peut fournir à l’appelant un résultat à utiliser. L’instruction return termine l’appel et renvoie sa valeur. Au point d’appel, l’appel représente cette valeur renvoyée.
Stocker et combiner des résultats
def rectangle_area(width, height):
return width * height
area = rectangle_area(4, 2.5)
print(area)
print(rectangle_area(3, 4) + rectangle_area(2, 5))
Le premier appel renvoie 10,0, qui est affecté à area ; le premier print l’affiche. Dans la dernière ligne, les deux appels renvoient 12 et 10. Python additionne ces résultats et affiche « 22 ». La fonction elle-même ne contient pas de print : elle peut donc fournir un résultat à stocker ou une partie d’un calcul plus large.
Une valeur renvoyée peut aussi être testée dans une condition ou transmise à une autre fonction. Cela distingue la tâche de calcul de la décision de l’appelant sur la façon d’utiliser la réponse.
Afficher et renvoyer ont des rôles différents
def double_print(n):
print(n * 2)
result = double_print(5)
print(result)
L’appel affiche « 10 », mais ce nombre affiché n’est pas renvoyé comme résultat. double_print atteint la fin de son corps et renvoie donc None. La dernière ligne affiche par conséquent « None ».
| Opération | Destination de la valeur |
|---|---|
print(value) | L’affiche pour une personne. |
return value | La transmet à l’appelant pour que le programme l’utilise. |
double_print(5) + 1 affiche d’abord « 10 », puis déclenche TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'. Remplace le corps par return n * 2 lorsque l’appelant a besoin du nombre doublé. Une fonction destinée uniquement à produire un effet, comme afficher un message, peut tout à fait renvoyer None ; on appelle parfois ces fonctions des procédures. Une fonction qui renvoie un résultat utile est parfois appelée fonction avec valeur de retour.
S’arrêter au premier return exécuté
def to_fahrenheit(celsius):
return celsius * 9 / 5 + 32
print("Converted")
print(to_fahrenheit(20))
Cela affiche « 68.0 ». Le print dans le corps n’est jamais atteint, car return a déjà terminé l’appel. Supprime cette instruction inaccessible ou déplace une action nécessaire avant le return. La conversion renvoie des flottants car / produit un flottant. Les entrées 100 et -40 donnent 212,0 et -40,0.
Un return seul, sans expression, termine aussi un appel en renvoyant None. Chaque appel de fonction a un résultat, même lorsqu’aucune valeur utile n’a été fournie.
Rendre les résultats visibles dans un fichier programme
Dans un fichier, un rectangle_area(3, 4) placé seul calcule 12 puis abandonne le résultat inutilisé. Utilise print(rectangle_area(3, 4)) pour l’afficher ou affecte-le à une variable. La console interactive affiche les résultats des expressions sauf None : un essai réussi dans la console peut donc sembler différent de l’exécution de la même ligne dans un fichier.
Points clés
return valuetermine l’appel et fait que l’appel représente cette valeur.- Afficher montre une valeur ; renvoyer la rend disponible pour l’appelant.
- Atteindre la fin du corps ou utiliser un
returnseul donneNone. - Les instructions après un return exécuté ne s’exécutent pas pendant cet appel.
- Utilise un résultat renvoyé en le stockant, en l’affichant, en le testant ou en le combinant.
3.2 Renvoyer depuis différents chemins et combiner les résultats
Des entrées différentes peuvent nécessiter des réponses différentes. Une fonction peut avoir plusieurs instructions return, mais un appel s’arrête à la première qu’il exécute. Suis le chemin réellement emprunté dans ses branches et ses boucles pour trouver le résultat.
Ordonner les tests qui se recoupent
def letter_grade(score):
if score >= 90:
return "A"
if score >= 80:
return "B"
if score >= 70:
return "C"
return "F"
Pour 85, le premier test est faux et le deuxième est vrai. La fonction renvoie « B » sans tester les conditions restantes. Pour 42, les trois tests sont faux : le return final fournit donc « F ». Des instructions if distinctes fonctionnent parce que chaque branche dont le test est vrai termine l’appel.
Le seuil le plus élevé doit ici être vérifié en premier. Si score >= 70 venait en premier, un score de 95 renverrait « C ». Lorsque des intervalles se recoupent, une condition large placée tôt peut masquer une réponse ultérieure plus précise.
Couvrir le chemin sans branche correspondante
def sign(n):
if n > 0:
return "positive"
elif n < 0:
return "negative"
return "zero"
La dernière ligne traite zéro. Sans elle, sign(0) atteindrait la fin et renverrait None. Suis une entrée pour chaque branche et pour tout cas restant ; tester seulement des entrées positives et négatives laisserait passer cet oubli.
Renvoyer une comparaison booléenne
def is_even(n):
return n % 2 == 0
if is_even(10):
print("Even")
La comparaison produit déjà True ou False. is_even(10) renvoie True, tandis que is_even(7) renvoie False. Utilise directement le résultat dans une condition. Un == True supplémentaire n’apporte rien au test.
Terminer une recherche avant de conclure à l’absence de correspondance
def smallest_divisor(n):
for d in range(2, n):
if n % d == 0:
return d
return n
Pour 91, les diviseurs possibles de 2 à 6 échouent, puis 7 le divise sans reste. Renvoyer 7 termine à la fois la boucle et la fonction. Pour 13, la boucle ne trouve aucun diviseur : le return final donne donc 13.
Un test de primalité doit permettre à la recherche de continuer après l’échec d’un diviseur possible :
def is_prime(n):
if n < 2:
return False
for d in range(2, n):
if n % d == 0:
return False
return True
Le True final est hors de la boucle. Le placer dans un else à l’intérieur de la boucle provoquerait un retour après la vérification du premier diviseur possible seulement : 9 serait accepté à tort parce qu’il n’est pas divisible par 2. Avec la fonction corrigée, 9 et 1 donnent False ; 2, 7 et 97 donnent True. Pour 2, la boucle n’a aucun diviseur à essayer et l’exécution atteint le True final.
Renvoyer deux valeurs
def share(total, people):
return total // people, total % people
each, left = share(17, 5)
print(each, left)
L’appel renvoie un tuple, un résultat regroupé contenant 3 et 2. L’affectation le dépaquette en deux noms : la sortie est donc « 3 2 ». Afficher directement l’appel montrerait « (3, 2) ». Le nombre de noms doit correspondre au nombre de valeurs dépaquetées.
Combiner les appels de l’intérieur vers l’extérieur
def add(a, b):
return a + b
def to_fahrenheit(celsius):
return celsius * 9 / 5 + 32
print(to_fahrenheit(add(10, 15)))
add renvoie d’abord 25. Cette valeur devient l’argument de to_fahrenheit, qui renvoie 77,0. Enfin, print affiche « 77.0 ». Chaque appel interne doit renvoyer la valeur dont la fonction suivante a besoin.
Points clés
- Le premier return exécuté termine un appel : ordonne donc soigneusement les tests qui se recoupent.
- Prévois un résultat utile pour chaque chemin d’entrée que la fonction doit traiter.
- Une fonction booléenne peut renvoyer directement une comparaison.
- Dans une boucle de recherche, renvoie un résultat trouvé ; indique l’absence de correspondance après l’échec de tous les candidats.
- Des valeurs renvoyées séparées par des virgules forment un tuple qui peut être dépaqueté.
- Dans des appels imbriqués, le résultat de l’appel interne devient l’argument de l’appel externe.
4Savoir où vivent les variables : portée locale et portée globale
Un nom dans une fonction peut sembler identique à un nom extérieur tout en désignant une variable distincte. La portée indique où un nom peut être utilisé, et l’affectation aide à déterminer quel nom Python désigne. Tu vas suivre les paramètres et les autres variables locales pendant un appel, distinguer la réaffectation de la modification d’une liste partagée et lire des paramètres globaux. Tu corrigeras aussi une erreur de portée courante et rendras explicites les valeurs qui changent dans les appels.
4.1 Manipuler des variables locales et des paramètres
La portée indique où un nom peut être utilisé. Les paramètres et les noms auxquels une valeur est affectée dans une fonction sont locaux à l’appel de cette fonction. Un appelant et une fonction peuvent utiliser des noms similaires sans partager les mêmes variables locales.
Garder les noms locaux dans leur appel
def make_greeting():
message = "Hi"
print(message)
make_greeting()
Cela affiche « Hi ». Ajouter print(message) après l’appel déclenche NameError: name 'message' is not defined : le nom local n’est pas disponible à cet endroit. Pour rendre la valeur disponible à l’appelant, renvoie-la et stocke-la :
def make_greeting():
return "Hi"
message = make_greeting()
print(message)
Le message au premier niveau du fichier est une nouvelle variable de l’appelant qui reçoit la valeur renvoyée. La fonction ne rend pas ses propres noms locaux visibles à l’extérieur.
Chaque appel reçoit de nouvelles variables locales. Si un corps affecte count = 0, ajoute 1 et l’affiche, deux appels affichent « 1 » et « 1 ». Le second appel ne continue pas avec le compteur du premier. Différentes fonctions peuvent aussi utiliser indépendamment des noms locaux comme total.
Suivre le masquage et la recherche des noms
x = 10
def show():
x = 5
print(x)
show()
print(x)
La sortie est « 5 » puis « 10 ». La variable locale x masque la variable globale x dans show ; l’affectation ne modifie pas la valeur au premier niveau du fichier. Une variable globale appartient à la portée du premier niveau du fichier. Les affectations ordinaires hors des fonctions créent des variables globales.
Pour une fonction définie au premier niveau du fichier, Python cherche un nom parmi ses noms locaux, puis parmi les noms globaux du fichier, puis parmi les noms natifs comme print. La première correspondance l’emporte. Les noms locaux et globaux sont donc deux endroits différents à vérifier lorsqu’une valeur semble incorrecte.
Réaffecter un paramètre ne modifie pas la variable de l’appelant
def add_bonus(points):
points = points + 10
print(points)
score = 50
add_bonus(score)
print(score)
points commence avec la valeur 50. Sa réaffectation locale lui donne la valeur 60 : la première sortie est donc « 60 ». La variable score de l’appelant vaut toujours 50. Pour mettre explicitement ce nom à jour, utilise une fonction qui renvoie points + 10, puis écris score = add_bonus(score).
Modifier une liste est une opération différente
Une liste peut être partagée par deux noms :
def add_guest(guests, name):
guests.append(name)
party = ["Ana"]
add_guest(party, "Ben")
print(party)
Le paramètre guests et la variable party de l’appelant désignent la même liste. append modifie le contenu de cette liste : la sortie est donc « ['Ana', 'Ben'] ». Affecter guests = [] dans la fonction ferait en revanche désigner une nouvelle liste au seul nom local ; party désignerait toujours la liste d’origine. Lorsque tu suis un argument de type liste, demande-toi si la ligne modifie l’objet partagé ou réaffecte seulement un nom local.
Points clés
- Les paramètres et les noms auxquels une valeur est affectée dans une fonction sont locaux à son appel.
- Chaque appel reçoit de nouvelles variables locales ; les valeurs de retour transmettent les résultats vers l’extérieur.
- Un nom local peut masquer un nom global sans modifier la valeur globale.
- Réaffecter un paramètre laisse la variable de l’appelant inchangée.
- Modifier une liste partagée change la liste que voit l’appelant.
4.2 Utiliser les variables globales avec prudence
Une fonction peut lire un nom global sans déclaration. Affecter une valeur à un nom dans son corps suit une règle différente, et confondre ces opérations est une cause courante d’UnboundLocalError.
Lire un paramètre fixe
TAX_RATE = 0.25
def tax(amount):
return amount * TAX_RATE
print(tax(80))
La sortie est « 20.0 ». amount est local ; TAX_RATE est lu parmi les noms globaux du fichier. Par convention, les majuscules marquent une constante et indiquent que le programme doit laisser ce paramètre fixe. Python n’impose pas cette convention.
Une affectation rend un nom local dans tout le corps
total = 0
def add_to_total(amount):
total = total + amount
add_to_total(5)
L’affectation rend total local dans toute la fonction add_to_total. Pour calculer le membre de droite, Python essaie de lire ce nom local avant qu’il ait une valeur. Il ne se rabat pas sur le total global. L’appel déclenche UnboundLocalError: cannot access local variable 'total' where it is not associated with a value.
La décision repose sur tout le corps, pas seulement sur les lignes déjà exécutées. Un corps avec print(count) suivi de count = 10 considère aussi count comme local à la ligne d’affichage. Un count global ne peut pas fournir la valeur locale manquante.
Déclarer une affectation globale délibérée
total = 0
def add_to_total(amount):
global total
total = total + amount
add_to_total(5)
add_to_total(7)
print(total)
La lecture et l’affectation désignent maintenant toutes deux le nom global : la sortie est donc « 12 ». Place global total avant toute utilisation de total dans la fonction. Utiliser le nom avant sa déclaration est une erreur de syntaxe.
Une déclaration seule ne crée pas de valeur. Une affectation ultérieure peut créer une variable globale qui n’existait pas : le corps d’une fonction contenant global level puis level = 1 crée le level global lors de son appel.
Montrer le changement par les entrées et un résultat
Le même total cumulé peut être écrit avec une interface explicite :
def add_to_total(total, amount):
return total + amount
total = 0
total = add_to_total(total, 5)
total = add_to_total(total, 7)
print(total)
Cela affiche aussi « 12 ». Chaque appel montre l’ancienne valeur transmise, et l’affectation montre où va la nouvelle valeur. Tu peux vérifier add_to_total(10, 3) indépendamment, sans initialiser d’abord un état global caché. Lorsque plusieurs fonctions modifient la même variable globale, leur comportement dépend de leur ordre d’exécution.
| Opération dans une fonction | Déclaration nécessaire ? |
|---|---|
| Lire un paramètre global | Non. |
| Réaffecter un nom global | global name avant utilisation. |
| Ajouter un élément à une liste globale existante | Non ; le nom n’est pas réaffecté. |
Lire une liste partagée et modifier son contenu utilise la référence existante. Faire désigner une autre liste à ce nom global est une affectation : la règle d’affectation s’applique donc.
Points clés
- Lis un nom global sans déclaration particulière.
- Une affectation n’importe où dans une fonction rend ce nom local, sauf s’il est déclaré global.
- La lecture d’un nom local auquel aucune valeur n’a été affectée déclenche
UnboundLocalError. - Place
global nameavant d’utiliser un nom que la fonction réaffecte volontairement au niveau global. - Privilégie les paramètres et les valeurs de retour lorsqu’une valeur changeante peut être transmise explicitement.
- Modifier une liste et réaffecter son nom suivent des règles différentes.
5Documenter et concevoir des programmes avec des fonctions
De bonnes fonctions ont besoin de tâches clairement définies ainsi que d’un code correct. L’appelant doit pouvoir voir ce dont une fonction a besoin, ce qu’elle renvoie et les effets qu’elle produit sans étudier chaque ligne de son corps. Tu vas écrire des docstrings, diviser un programme complet en fonctions auxiliaires et les relier au moyen d’une petite fonction main. Tu vérifieras ensuite chaque partie à l’aide de résultats attendus, d’entrées aux limites et des indices d’une trace d’appels.
5.1 Documenter des fonctions avec des docstrings
L’appelant doit connaître la tâche d’une fonction sans lire toute son implémentation. Une docstring fournit cette description. Python reconnaît une chaîne comme la docstring de la fonction lorsqu’elle est la première instruction du corps.
Écrire d’abord une courte description
def to_fahrenheit(celsius):
"""Convert a temperature from degrees Celsius to degrees Fahrenheit."""
return celsius * 9 / 5 + 32
print(to_fahrenheit.__doc__)
La sortie est la phrase entre les guillemets. Python stocke la docstring dans __doc__ ; les triples guillemets ne font pas partie de la phrase stockée. help(to_fahrenheit) affiche la description avec la signature to_fahrenheit(celsius). Transmets le nom de la fonction à help, sans appeler la fonction.
La convention courante consiste à utiliser trois guillemets doubles, même pour une docstring d’une ligne. Commence par une instruction comme « Renvoyer l’aire d’un rectangle. » et termine par un point. Garde une courte description et ses guillemets de fermeture sur une seule ligne. Tu n’as pas besoin de répéter le nom de la fonction et la liste des paramètres, car l’aide les affiche déjà.
Ajouter des détails lorsque les appelants en ont besoin
def split_bill(total, people, tip_rate=0.2):
"""Return each person's share of a bill, including the tip.
total: the bill before the tip
people: the number of people sharing the bill
tip_rate: the tip as a fraction of the bill (default 0.2)
"""
return total * (1 + tip_rate) / people
La première ligne indique le résultat. Une ligne vide la sépare des détails sur les entrées. La valeur par défaut est documentée comme 0,2, une fraction de l’addition ; cela évite qu’un appelant prenne 20 pour la valeur voulue pour un pourboire de 20 %. Les guillemets de fermeture d’une docstring multiligne sont placés sur leur propre ligne.
Pour split_bill(84, 4), la fonction applique le pourboire par défaut et renvoie 25,2. L’appelant peut comprendre ce que signifient les trois entrées avant de choisir les arguments. Indique les unités lorsqu’elles comptent et décris les effets comme l’affichage, afin que l’appelant puisse prévoir le résultat et le comportement visible.
Distinguer la documentation des commentaires
| Forme | Rôle principal |
|---|---|
| Première chaîne dans le corps | Décrit la fonction pour son appelant et apparaît dans help. |
Commentaire # dans le corps | Explique un détail du code à la personne qui lit l’implémentation. |
Une chaîne placée après une affectation ou une autre instruction du corps n’est pas la docstring de la fonction. C’est une expression de chaîne inutilisée, et __doc__ vaut None si aucune docstring ne figure en première instruction. Un commentaire # ne devient pas non plus la description de l’aide.
Écris le résumé au moment de définir la tâche de la fonction. Si la phrase nécessite plusieurs actions sans rapport, demande-toi si la fonction devrait être décomposée. Lorsque tu modifies les paramètres, les valeurs par défaut, les valeurs renvoyées ou les effets d’affichage, mets la docstring à jour en même temps ; les appelants s’y fient comme partie de l’interface.
Points clés
- La docstring d’une fonction est la première instruction de son corps.
- Utilise trois guillemets doubles et une courte phrase exprimant une instruction, terminée par un point.
- Pour les descriptions plus longues, sépare le résumé des détails par une ligne vide.
- Décris les entrées utiles, les unités, les valeurs par défaut, les résultats et les effets.
- Lis la documentation stockée avec
help(name)ouname.__doc__.
5.2 Décomposer un problème en fonctions
La décomposition consiste à diviser une tâche en travaux plus petits. Chaque fonction est responsable d’une tâche, avec des entrées explicites et un résultat ou un effet explicite. Le programme principal peut alors se lire comme une courte suite d’étapes nommées.
Prévoir les données avant d’écrire les corps
Pour un programme qui indique la moyenne de notes de contrôle et une note sous forme de lettre, distingue trois tâches : lire les notes, calculer une moyenne et choisir une lettre. Décide de ce que chaque fonction auxiliaire reçoit et renvoie. Garde l’affichage dans main, où les résultats se rejoignent.
def get_score(prompt):
return float(input(prompt))
def average(a, b, c):
return (a + b + c) / 3
def letter_grade(score):
if score >= 90:
return "A"
if score >= 80:
return "B"
if score >= 70:
return "C"
return "F"
def main():
first = get_score("Test 1: ")
second = get_score("Test 2: ")
third = get_score("Test 3: ")
avg = average(first, second, third)
print("Average:", round(avg, 1), "Grade:", letter_grade(avg))
main()
Avec les notes 78, 92 et 85, average renvoie 85,0. Ce résultat devient l’argument de letter_grade, qui renvoie « B ». L’affichage est « Average: 85.0 Grade: B ».
main coordonne la séquence ; elle n’a pas besoin de savoir comment letter_grade choisit sa réponse. Utiliser une fonction en connaissant sa tâche et son interface, sans suivre chaque instruction de son corps, relève de l’abstraction procédurale. Tu utilises déjà print de cette façon.
Fournir à l’appelant une interface claire
L’interface d’une fonction comprend son nom, ses paramètres, le résultat renvoyé et son comportement documenté. average(a, b, c) exige trois nombres et renvoie leur moyenne. Son appelant n’a pas besoin de répondre à une invite ni de récupérer du texte affiché pour obtenir ce nombre. Tu peux réécrire le calcul tout en conservant les entrées et la sortie convenues, et les appels existants continuent de fonctionner.
Utilise des noms comme calculate_total et print_receipt pour les actions, et is_even ou has_discount pour les questions booléennes. Des noms de paramètres comme price et quantity indiquent les valeurs attendues à chaque emplacement. Les noms d’une seule lettre peuvent convenir lorsque leur sens est clair, comme pour les trois entrées de average.
Transformer les éléments répétés en paramètres
Si plusieurs parties d’un programme affichent différents titres entre les mêmes lignes de signes égal, fais du titre un paramètre de print_heading(title). La structure répétée appartient à un seul corps, tandis que le texte variable appartient aux appels. Une modification ultérieure de la longueur des lignes ne demande alors qu’une seule correction.
Définis les fonctions de façon à rendre les tâches plus faciles à comprendre ou à réutiliser. Placer toutes les instructions dans une longue fonction main masque les tâches plus petites. Transformer chaque expression triviale en fonction auxiliaire utilisée une seule fois peut ajouter des noms sans améliorer la lisibilité. Un test utile consiste à vérifier si une courte phrase peut décrire chaque tâche ainsi que ses entrées et ses sorties.
Termine le fichier par l’appel effectif main() après toutes les définitions. Un programme qui ne contient que des définitions crée ses fonctions et se termine sans exécuter leurs corps.
Points clés
- Décompose la tâche en travaux dont les entrées et les sorties sont nommées.
- Sépare les calculs de la saisie et de l’affichage lorsqu’ils doivent être réutilisés ou vérifiés.
- Laisse
maincoordonner les fonctions auxiliaires et appellemain()après les définitions. - Utilise des paramètres pour les parties variables du code répété.
- Une interface stable permet aux appelants d’utiliser une fonction sans dépendre de son corps.
- Définis les fonctions de manière à rendre le programme plus facile à comprendre.
5.3 Construire et vérifier un programme fonction par fonction
Construire plusieurs fonctions avant d’en exécuter une seule rend un échec plus difficile à localiser. Le développement incrémental consiste à écrire une petite partie, à la vérifier, puis à ajouter la suivante. Tu conserves ainsi un programme qui fonctionne tout en réduisant la quantité de nouveau code à examiner.
Utiliser un bouchon pendant la conception
Un bouchon possède l’en-tête prévu et un corps provisoire. Une docstring et pass gardent la définition valide, mais la fonction renvoie None jusqu’à son implémentation. Une valeur de retour fixe peut aider à tester l’affichage d’un appelant sans prétendre que le calcul réel fonctionne déjà.
Commence par une fonction auxiliaire de calcul dont tu peux déterminer le résultat indépendamment. Une fois qu’elle se comporte correctement, relie-la à la fonction auxiliaire suivante. Garde la saisie interactive pour le moment où les calculs pourront être vérifiés par des appels directs.
Déterminer les résultats attendus avant l’exécution
Avec les fonctions average et letter_grade, les notes 70, 75 et 72 ont une moyenne d’environ 72,33 : la note sous forme de lettre attendue est donc « C ». Vérifie les deux étapes :
print(average(70, 75, 72))
print(letter_grade(average(70, 75, 72)) == "C")
Les sorties sont « 72.33333333333333 » et « True ». La comparaison teste directement la note attendue ; regarder uniquement la sortie d’un programme sans attente indépendante peut laisser passer une réponse erronée mais plausible.
Tester les limites ainsi que les entrées ordinaires
Pour un seuil de 90, teste 90 et 89,9. La fonction de notation correcte renvoie « A » et « B ». Si sa première condition était score > 90, seule la vérification exactement au seuil révélerait que 90 passe à tort au test suivant.
Inclus une valeur courante, les seuils exacts, des valeurs proches et des entrées extrêmes que la fonction est censée traiter. Pour la fonction de notation, vérifier 70 et 0 permet de tester le seuil de réussite le plus bas et le chemin final « F ». Une vérification comme print(letter_grade(85) == "B") est facile parce que la fonction prend une valeur et renvoie son résultat.
Lire la trace d’appels et examiner la valeur reçue
Supposons que main appelle letter_grade(input("Score: ")). Saisir « 85 » envoie une chaîne dans une comparaison avec un nombre. L’erreur finale est TypeError: '>=' not supported between instances of 'str' and 'int'. La trace d’appels désigne la comparaison dans la fonction auxiliaire, tandis qu’une ligne d’appel précédente désigne main.
L’échec se produit lors de la comparaison, mais la correction doit être faite là où la saisie est préparée : convertis-la avec float() avant de la transmettre. Un print("letter_grade got", score) temporaire en première ligne aide à révéler une entrée inattendue. Si son type n’est pas clair, examine l’appelant et la conversion qu’il utilise. Supprime les affichages de débogage une fois le bug corrigé.
Associer les symptômes aux causes probables
| Symptôme | Point à vérifier |
|---|---|
Un résultat vaut None | Un return manquant ou un chemin non couvert. |
| Aucun effet n’apparaît | Un appel manquant ou un résultat renvoyé inutilisé. |
| Un résultat plausible a le mauvais sens | Des arguments inversés. |
NameError | Un nom de fonction ou de variable mal orthographié ou indisponible. |
Après avoir corrigé une fonction auxiliaire, relance les vérifications qui exercent les chemins concernés et l’appelant qui la relie au programme.
Points clés
- Construis et vérifie une fonction avant d’ajouter la suivante.
- Calcule les résultats attendus indépendamment avant de les comparer aux résultats des appels.
- Teste les seuils exacts et les valeurs proches pour détecter les erreurs de comparaison.
- Utilise la trace d’appels pour trouver l’échec et ses appelants.
- Supprime les affichages de débogage temporaires une fois le problème corrigé.
Fonctions Python : exemples
1Écrire une fonction et suivre ses appels
10 étapes
- 1IntroductionDonner un nom à une tâche
Une fonction te permet d’écrire une tâche utile une seule fois et de choisir quand l’exécuter. Tu vas commencer par une salutation, puis suivre un rapport qui appelle une fonction auxiliaire.
Pendant ta lecture, distingue deux questions : « Python a-t-il créé cette fonction ? » et « Le programme l’a-t-il déjà appelée ? ». La première rend le nom disponible ; la seconde démarre le travail du corps. Cette distinction explique pourquoi un fichier rempli de définitions peut se terminer sans rien afficher.
- 2ExplicationÉcrire le corps réutilisable
def greet(): print("Hello!") print("Welcome to Python.")L’en-tête utilise
def, un nom, des parenthèses et deux-points. Les deux lignes indentées de quatre espaces forment le corps. Python crée la fonction lorsque cette définition s’exécute, mais aucun des deux affichages ne s’exécute encore.La prochaine instruction non indentée sera hors de la fonction. L’indentation indique à Python où cette tâche se termine ; elle fait partie de la structure du programme.
- 3ExempleL’exécuter deux fois
Ajoute ces lignes après la définition :
greet() greet()Le premier appel entre dans le corps et affiche « Hello! » suivi de « Welcome to Python. ». Le second appel reprend à la première ligne du corps et affiche à nouveau les deux messages. Il y a quatre lignes de sortie.
Les parenthèses vides restent nécessaires :
greetseul désigne l’objet fonction. Il ne l’appelle pas, etprint(greet)affiche une description de la fonction au lieu de la salutation. - 4DéfiPrévoir l’effet d’un appel manquant
Qu’affiche ce fichier ?
def ready(): print("Ready") ready print("Waiting")---reveal---
Il affiche seulement « Waiting ». La définition crée
ready, et le nom seul désigne cette fonction sans l’exécuter. Pour afficher aussi le message, remplacereadyparready(). L’appel s’exécuterait alors avant le dernier affichage et donnerait « Ready » et « Waiting » sur des lignes distinctes. - 5ConseilGarder des noms et des corps utilisables
Utilise des noms comme
print_receipt: des mots en minuscules reliés par des traits de soulignement qui décrivent la tâche. Évite de remplacer un nom natif. Affecter du texte àinputmasque la fonction : uninput(...)ultérieur essaie donc d’appeler du texte et échoue.Un corps inachevé a besoin d’une instruction. Utilise un
passindenté comme instruction provisoire. Un commentaire seul ne constitue pas un corps, et unpassnon indenté se trouverait hors de la fonction. - 6ExempleEntrer dans un appelant
def line(): print("----------") def banner(): line() print(" REPORT") line() print("Start") banner() print("End")Les deux définitions s’exécutent d’abord sans rien afficher. L’instruction au premier niveau affiche « Start », puis
banner()entre dans le corps de la bannière. Sa première ligne appelleline: la bannière doit donc attendre que cette fonction auxiliaire affiche ses tirets. Ne passe pas au titre avant que la fonction auxiliaire soit terminée. - 7ExplicationReprendre un niveau à la fois
Lorsque
linese termine, l’exécution reprend à l’affichage du titre dansbanner. La bannière appelle ensuitelineune seconde fois, ce qui produit la seconde ligne de tirets. Lorsque la bannière se termine, le programme principal reprend et affiche « End ».La pile d’appels de Python enregistre les appels non terminés et leurs points de retour. Pendant que la fonction auxiliaire s’exécute, la bannière et le programme principal attendent. Un suivi sur papier peut marquer ces points de retour et noter la sortie au moment où chaque affichage s’exécute.
- 8DéfiSuivre un autre appel de fonction auxiliaire
Quel est l’ordre de la sortie ?
def inner(): print("I") def outer(): print("O") inner() print("P") outer() print("Q")---reveal---
Les lignes sont « O », « I », « P » et « Q ». Le corps externe affiche d’abord, attend
inner, puis reprend à son affichage suivant. Ce n’est qu’après la fin deouterque la dernière instruction au premier niveau s’exécute. L’ordre des définitions ne détermine pas à lui seul l’ordre de la sortie. - 9DéfiDéplacer une définition sans risque
Un fichier définit
showavec un corps qui appelleborder. Il définit ensuiteborder, puis se termine par une boucle qui appelleshow()deux fois. La définition plus basse de la fonction auxiliaire provoquera-t-elle une erreur, et combien de foisborders’exécute-t-elle ?---reveal---
Le programme fonctionne : les deux définitions ont été exécutées avant que la boucle appelle
show. Chaque appel entre dansshowà la première ligne de son corps et atteint un appel àborder: la fonction auxiliaire s’exécute donc deux fois. Déplacer la boucle au-dessus de la définition de la fonction auxiliaire rendrait son nom indisponible au premier moment où il est nécessaire. - 10RécapitulatifLire à partir de la première instruction exécutée
Lorsque tu suis l’exécution d’un programme avec des fonctions :
- Vérifie l’en-tête et l’indentation pour repérer chaque corps.
- Commence par les instructions au premier niveau et n’entre dans un corps que par un appel.
- Marque l’instruction suivante de l’appelant avant de suivre une fonction auxiliaire.
- Note la sortie lorsque son affichage s’exécute.
Si un appel échoue, lis la dernière erreur de la trace d’appels, puis examine la ligne du corps en échec et l’appelant qui y a conduit. Le chemin des appels est souvent la clé pour comprendre l’erreur.
2Renseigner les emplacements des paramètres
13 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionRéutiliser une tâche avec différentes valeurs
- 2ExempleAssocier la première et la deuxième entrée
- 3ExplicationÉvaluer les arguments avant le corps
- 4DéfiVérifier le nombre d’arguments
- 5ExplicationUtiliser des noms pour montrer les rôles
- 6DéfiCorriger un emplacement renseigné deux fois
- 7ConseilLire les options nommées des fonctions natives
- 8ExempleRendre le choix courant facultatif
- 9DéfiSauter un choix facultatif grâce au nom
- 10Point cléUne valeur par défaut garde sa valeur à la création
- 11ExempleComprendre pourquoi une liste par défaut conserve ses éléments
- 12DéfiCombiner valeurs par défaut et entrées nommées
- 13RécapitulatifComparer l’appel à l’en-tête
3Suivre les valeurs jusqu’à l’appelant
14 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionObserver ce que reçoit l’appelant
- 2ExempleRemplacer l’appel par son résultat
- 3ExplicationDistinguer l’affichage du résultat
- 4DéfiTrouver la valeur utilisée dans l’addition
- 5ConseilVérifier où l’appel s’exécute
- 6ExempleS’arrêter à la première note correspondante
- 7DéfiTraiter l’entrée entre les branches
- 8Point cléLaisser une comparaison répondre à la question
- 9ExempleRenvoyer un diviseur trouvé
- 10DéfiCorriger un résultat positif renvoyé trop tôt
- 11ExempleDépaqueter un résultat regroupé
- 12ExempleTransmettre un résultat interne vers l’extérieur
- 13DéfiCombiner un retour anticipé et un résultat
- 14RécapitulatifSuivre ensemble les chemins et les valeurs renvoyées
4Suivre les noms et les objets partagés
11 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionSe demander où appartient le nom
- 2ExempleDonner à chaque appel son propre compteur
- 3ExplicationDistinguer les noms masqués
- 4DéfiRendre explicite la mise à jour dans l’appelant
- 5ExempleSuivre une liste partagée par un paramètre
- 6ExempleLire une variable globale sans déclaration
- 7Point cléL’affectation détermine la portée locale dès le départ
- 8DéfiChoisir la portée d’une mise à jour
- 9LienFaire passer la valeur changeante par l’appel
- 10DéfiDistinguer mutation et réaffectation
- 11RécapitulatifNommer l’opération avant de prévoir son effet
5Concevoir et vérifier un compte rendu de notes
12 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionConstruire un programme à partir de tâches claires
- 2ExemplePlacer la description là où l’aide peut la trouver
- 3ExplicationAjouter les détails qui influent sur un appel
- 4DéfiTrouver la documentation manquante
- 5ExplicationChoisir une tâche pour chaque fonction auxiliaire
- 6ExempleRelier les fonctions auxiliaires dans main
- 7DéfiSéparer le calcul de l’affichage
- 8ConseilConserver un programme qui fonctionne pendant la construction
- 9ExempleVérifier un seuil qui peut révéler un bug
- 10DéfiTrouver où un type incorrect entre
- 11DéfiFaire concorder la documentation et une vérification
- 12RécapitulatifUtiliser l’interface pour guider les vérifications
Fonctions Python : QCM
Série 1 : Suivre les entrées, la portée et les résultats manquants10 Questions Pratiques
Question 1 sur 10
Comment compléter ce corps de fonction inachevé pour que le fichier soit valide mais que la fonction ne fasse encore rien ?
def print_ticket():
# Work to be added later
Afficher la réponseMasquer la réponse
pass indenté est une instruction valide pour le corps qui ne fait rien. Les commentaires seuls ne constituent pas le corps requis : ajouter un autre commentaire laisse donc la définition incomplète. Une instruction non indentée se trouve hors de la fonction et ne peut pas fournir son corps manquant.Question 2 sur 10
Qu’affiche ce programme ?
def show_scaled(value, factor):
print(value * factor)
entry = "6"
show_scaled(entry, 3)
Afficher la réponseMasquer la réponse
entry contient du texte, et Python répète ce texte lorsqu’il est multiplié par l’entier 3. La sortie est « 666 », sans espaces ajoutées. Pour obtenir 18, il faudrait convertir le texte en nombre avant la multiplication ; le nom du paramètre n’effectue pas cette conversion.Question 3 sur 10
Quelle valeur est renvoyée ?
step = 4
def advance(position, amount=step):
return position + amount
step = 9
result = advance(10)
Afficher la réponseMasquer la réponse
def s’exécute, alors que step vaut 4. Omettre amount ajoute donc 4 à 10 et renvoie 14. Modifier ensuite step à 9 ne met pas à jour la valeur par défaut stockée ; pour obtenir 19, il faudrait transmettre explicitement la nouvelle valeur.Question 4 sur 10
Quelle modification unique permet à result de contenir 16 sans l’afficher dans la fonction auxiliaire ?
def square(n):
print(n * n)
result = square(4)
Afficher la réponseMasquer la réponse
n * n transmet directement 16 à l’affectation sans affichage dans la fonction auxiliaire. return print(n * n) affiche toujours le nombre et renvoie le résultat de print, qui est None. Un return seul après un affichage donne aussi None : il ne fournit donc pas le nombre calculé.Question 5 sur 10
Qu’est-ce qui est affiché ?
def pack(total, size):
return total // size, total % size
def double(n):
return n * 2
boxes, spare = pack(29, 6)
print(double(boxes) + spare)
Afficher la réponseMasquer la réponse
(4, 5) : boxes vaut donc 4 et spare vaut 5. Doubler le nombre de boîtes donne 8, puis ajouter 5 affiche « 13 ». Obtenir 14 revient à inverser les deux valeurs dépaquetées avant de doubler, ce qui ne respecte pas l’ordre de retour.Question 6 sur 10
Qu’est-ce qui est affiché après les deux appels ?
def add_guest(guests):
guests.append("Sol")
def replace_guests(guests):
guests = ["Tao"]
party = ["Ren"]
add_guest(party)
replace_guests(party)
print(party)
Afficher la réponseMasquer la réponse
add_guest ajoute « Sol » à la même liste que celle désignée par party. replace_guests ne fait que réaffecter son paramètre local à une nouvelle liste : party désigne donc toujours ['Ren', 'Sol']. S’attendre à ['Tao'] revient à confondre la redirection du nom local avec le remplacement de la référence de l’appelant.Question 7 sur 10
Que se passe-t-il lorsque inspect() est appelée ?
count = 11
def inspect():
print(count)
count = 2
inspect()
Afficher la réponseMasquer la réponse
count le rend local dans tout le corps, y compris lors de l’affichage précédent. Ce nom local n’a pas de valeur lorsque l’instruction d’affichage essaie de le lire : l’appel déclenche donc UnboundLocalError. Python n’utilise pas d’abord le 11 global avant de passer à la portée locale lorsqu’il atteint l’affectation.Question 8 sur 10
Que contient show.__doc__ ?
def show():
value = 2
"""Display the current value."""
print(value)
Afficher la réponseMasquer la réponse
show.__doc__ vaut None. Les triples guillemets ne suffisent pas à eux seuls ; déplace la description au-dessus de l’affectation pour la stocker comme documentation.Question 9 sur 10
Afficher la réponseMasquer la réponse
main ne fait que déplacer la répétition et exige toujours plusieurs modifications pour changer ce comportement commun.Question 10 sur 10
> 50 écrit par erreur ?Afficher la réponseMasquer la réponse
Série 2 : Lire les appels et suivre leurs résultats10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Quelle sortie ce programme produit-il ?
def announce():
print("Open")
print("Ready")
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Quel est l’ordre de la sortie ?
def mark():
print("M")
def stage():
print("S")
mark()
print("T")
print("R")
stage()
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
Qu’affiche cet appel ?
def describe_trip(origin, destination):
print(origin, "to", destination)
describe_trip("Mesa", "Salem")
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
Comment appeler cette fonction en utilisant « Inez » pour la personne et « West » pour la salle ?
def show_booking(person, room):
print(person, room)
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Qu’est-ce qui est affiché ?
def label(text, copies=2):
print(text * copies)
label("Go")
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Qu’affiche la dernière ligne ?
def triple(value):
print(value * 3)
answer = triple(4)
print(answer)
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Que renvoie cette fonction pour first_factor(25) ?
def first_factor(n):
for candidate in range(2, n):
if n % candidate == 0:
return candidate
return n
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
Quelles sont les deux lignes de sortie ?
level = 7
def show_level():
level = 3
print(level)
show_level()
print(level)
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Quel est le rôle de la première chaîne dans cette fonction ?
def square(n):
"""Return the square of n."""
return n * n
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 3 : Diagnostiquer les appels et corriger le comportement du programme10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Pourquoi ce programme fonctionne-t-il alors que tick est définie sous report ?
def report():
tick()
def tick():
print("Done")
report()
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Quelle valeur d’argument parvient à width ?
def show_width(width):
print(width)
base = 8
show_width(base + 3)
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
Pourquoi cet appel échoue-t-il ?
def mark_pages(first, last):
print(first, last)
mark_pages(4, first=9)
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
Quelles sont les deux listes affichées ?
def collect(value, bucket=[]):
bucket.append(value)
return bucket
print(collect("red"))
print(collect("blue", []))
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Quelle est la sortie complète ?
def shift(n):
return n + 2
print("shifted")
shift(5)
print("done")
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Une fonction doit renvoyer True exactement lorsqu’un entier est premier. Pourquoi ce corps accepte-t-il 35 à tort ?
def is_prime(n):
if n < 2:
return False
for d in range(2, n):
if n % d == 0:
return False
else:
return True
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Qu’est-ce qui est affiché ?
total = 2
def add(amount):
global total
total = total + amount
return total
first = add(4)
second = add(first)
print(total, second)
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
if score >= 60: après que l’appelant a transmis input("Score: "). Quelle correction traite le type de la saisie ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 4 : Combiner les règles des fonctions dans de nouvelles situations10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Qu’est-ce qui est affiché ?
def outer():
inner()
print("Y")
outer()
def inner():
print("X")
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
Quelle est la sortie complète, sauts de ligne compris ?
print("N", "S", sep="/", end="|")
print("E", "W", sep="-")
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
Un nouvel appel qui omet items doit commencer avec une nouvelle liste, mais une liste fournie doit être complétée en place. Quel corps de remplacement est correct ?
def add_code(code, items=None):
# replacement body
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Quelle modification permet à cette fonction de renvoyer le premier candidat correspondant, ou None seulement après l’échec de tous les candidats ?
def find_divisor(n):
for d in range(3, n):
if n % d == 0:
return d
else:
return None
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Qu’affiche la dernière ligne ?
def change(values):
values.append("B")
values = ["C"]
values.append("D")
return values
original = ["A"]
result = change(original)
print(original, result)
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Comment l’appelant peut-il mettre à jour stock explicitement sans que la fonction auxiliaire modifie une variable globale ?
stock = 18
def remove(stock, amount):
return stock - amount
# caller statement
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
pass. Son appelant ajoute le résultat de la fonction auxiliaire à 7 et obtient TypeError. Que faut-il implémenter ensuite ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Qu’est-ce qui est affiché ?
def add_fee(amount):
return amount + 3
def twice(amount):
return amount * 2
print(twice(add_fee(5)))
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Qu’est-ce qui est affiché ?
rate = 2
def scale(value, factor=rate):
return value * factor
def reset():
global rate
rate = 5
reset()
print(scale(3), scale(3, rate))
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Tu bloques sur ton propre exercice ? Aide aux Devoirs
Mots-Clés
A
Abstraction procédurale
letter_grade(avg) sans suivre chaque comparaison de seuil dans le corps.Affichage de débogage
Appel de fonction
greet() exécute la salutation, tandis qu’une ligne contenant seulement greet ne l’exécute pas.Appel imbriqué
print(to_fahrenheit(add(10, 15))), l’addition s’exécute avant la conversion, puis vient l’affichage.Appelant
banner() appelle line(), le corps de la bannière est l’appelant de la fonction qui trace une ligne.Argument
area(side + 1, 2), Python calcule le premier argument avant de commencer le corps de la fonction d’aire.Argument nommé
describe_pet(name="Milo", animal="cat") renseigne les paramètres dans un ordre lisible.Argument positionnel
describe_pet(animal, name), describe_pet("cat", "Milo") place « cat » dans animal.B
Bouchon
pass créent un bouchon valide, même si ses appels renvoient toujours None jusqu’à son implémentation.C
Chemin de retour
Constante
TAX_RATE = 0.25 pour calculer une taxe sans déclarer ce nom global.Corps de la fonction
print indentées sous def greet(): appartiennent toutes deux au corps de la fonction.D
Décomposition
Définition de fonction
def avec un en-tête et un corps indenté qui crée une fonction sous un nom.greet à def greet(): et attend un appel avant d’exécuter son corps.Dépaquetage
share(17, 5) renvoie 17 // 5, 17 % 5, l’affectation each, left = share(17, 5) place 3 dans each et 2 dans left.Développement incrémental
Docstring
Docstring d’une ligne
Docstring multiligne
tip_rate=0.2 est une fraction de l’addition, et non 20.E
En-tête
def, le nom de la fonction, les parenthèses des paramètres et deux-points.def print_line(length):, l’en-tête nomme la tâche et son entrée avant que le corps commence.É
État caché
F
Flot d’exécution
banner(), terminer ses appels de fonctions auxiliaires, puis afficher « End ».Fonction
print_receipt() chaque fois qu’il doit afficher un autre reçu.Fonction avec valeur de retour
Fonction booléenne
True ou False, souvent directement à partir d’une comparaison.return n % 2 == 0 permet d’utiliser is_even(n) directement comme condition d’un if.Fonction help
help affiche des informations sur une fonction, notamment sa signature et sa docstring stockée lorsqu’elle existe.help(to_fahrenheit) pour examiner la fonction de conversion sans lui fournir d’abord une température.Fonction main
main coordonne les petites tâches d’un programme en reliant les entrées, les résultats des fonctions auxiliaires et l’affichage final.main() exécute les étapes d’un compte rendu de notes après l’exécution de toutes les définitions des fonctions auxiliaires.I
Instruction global
global fait qu’un nom dans une fonction désigne la liaison au niveau du fichier pour les lectures et les affectations ultérieures.global total avant que la fonction utilise total pour mettre à jour un compteur cumulé partagé.Instruction pass
pass est une instruction provisoire qui n’effectue aucune action et permet au corps d’une fonction en cours de conception d’être valide en Python.pass peut être appelée pendant que son comportement réel d’affichage est encore en cours d’écriture.Instruction return
None.return width * height permet à l’appelant de stocker une aire ou de l’utiliser dans un autre calcul.Interface
M
Masquage
x = 5 alors que x = 10 est global, le x de la fonction auxiliaire donne 5 et un x global ultérieur donne toujours 10.Mutation
N
None
None est la valeur spéciale de Python qui signifie « aucune valeur » ; elle sert aussi à signaler qu’une entrée facultative a été omise.basket=None, la fonction peut créer une nouvelle liste dans if basket is None:.P
Paramètre
def area(width, height): donne à chaque appel de la fonction d’aire des noms locaux pour ses deux dimensions.Paramètre end
end de print contrôle le texte ajouté après les valeurs affichées ; il utilise un saut de ligne par défaut.end="..." permet à l’affichage suivant de continuer après les points au lieu de commencer une nouvelle ligne.Paramètre facultatif
milk="oat" tout en laissant à sa valeur par défaut un paramètre facultatif précédent qui indique le nombre de doses.Paramètre obligatoire
def greet(name, greeting="Hello"):, omettre name provoque une erreur d’argument manquant.Paramètre sep
sep de print contrôle le texte inséré entre les valeurs affichées ; il utilise une espace par défaut.print("a", "b", "c", sep="-") affiche les trois lettres sous la forme « a-b-c ».Passage d’arguments mixte
describe_pet("cat", name="Milo"), le premier emplacement est renseigné par position et le second par nom.Pile d’appels
Portée
make_greeting() n’est pas disponible pour un affichage au premier niveau après l’appel.Procédure
None.None.R
Réaffectation
points = points + 10 modifie le paramètre local et laisse le score de l’appelant inchangé.Résultat attendu
Retour anticipé
T
Test aux limites
> au lieu de >=.Trace d’appels
Tuple
return total // people, total % people regroupe une part et un reste.TypeError
TypeError signale une opération inadaptée sur une valeur ou un appel avec une combinaison d’arguments invalide.TypeError pour l’entrée manquante.U
UnboundLocalError
UnboundLocalError se produit lorsqu’une fonction essaie de lire un nom local avant que ce nom ait une valeur.count rend aussi local un print(count) précédent, même si une variable globale existe.V
Valeur de retour
area = rectangle_area(4, 2.5), area contient le résultat renvoyé 10,0 pour une utilisation ultérieure.Valeur par défaut
def greet(name, greeting="Hello"):, un appel peut omettre la salutation tout en fournissant le nom.Valeur par défaut mutable
Variable globale
x = 10 au premier niveau reste à 10 lorsqu’une fonction auxiliaire affecte sa propre variable locale distincte x = 5.Variable locale
count = 0, de sorte que deux appels peuvent afficher indépendamment la valeur 1.À propos de cette unité
Crée ton propre Matériel d'Étude
Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.