Académique Documents
Professionnel Documents
Culture Documents
●
Notion n°10 : Les exceptions en programmation
Retour sur l'appel de fonction (1) : Retour sur l'appel de fonction (2) :
Paramètres nommés Paramètres (nommés) optionnels
●
Nous savons qu'une fonction s'utilise (s'appelle) en écrivant son
nom suivi du n-uplet de ses arguments ; l'association entre
●
En Python, comme dans d'autres langages, il est aussi possible
paramètres formels et actuels se fait donc « par position » de définir une valeur par défaut pour certains paramètres
def foo(a,b,c,d): return((a + b*c) * 100 / d) ●
De cette façon, on pourra éviter de les fournir au moment de
...
x = foo(1,2,3,4) # Par position : a=1 b=2 c=3 d=4 donc x=175 l'appel, autrement dit, ces paramètres seront optionnels
y = foo(1,2,3,1) # Par position : a=1 b=2 c=3 d=1 donc y=700 (fournis de façon optionnelle)
●
En Python, comme dans d'autres langages, il est possible de ●
Dans le n-uplet des formels de la définition il faudra écrire les
rendre explicite l'affectation formel = actuel, mais il faut alors affectations formel = valeur-par-défaut dans le bon ordre
écrire :
– en premier les formels non optionnels
– en premier les actuels par position
– en dernier toutes les affectations explicites formel = actuel, – en dernier les formels optionnels
dans n'importe quel ordre
def foo(a,b,c,d=1): return((a + b*c) * 100 / d) # d est optionnel (par défaut égal à 1)
...
●
Cette modalité d'appel se dit « par argument nommé » x = foo(1,2,3,4) # Par position : a=1 b=2 c=3 d=4 donc x=175
Exemple : y = foo(1,2,3,1) # Par position : a=1 b=2 c=3 d=1 donc y=700
y = foo(1,2,3) # Par position : a=1 b=2 c=3 Par défaut : d=1 donc y=700
x = foo(1,2,3,d=4) # Par position : a=1 b=2 c=3 Nommés : d=4 donc x=175
y = foo(1,2,c=3,d=1) # Par position : a=1 b=2 Nommés : c=3 d=1 donc y=700 y = foo(c=3,d=1,a=1,b=2) # Nommés : a=1 b=2 c=3 d=1 donc y=700
3 4
y = foo(c=3,d=1,a=1,b=2) # Nommés : a=1 b=2 c=3 d=1 donc y=700 y = foo(c=3,a=1,b=2) # Nommés : a=1 b=2 c=3 Par défaut : d=1 donc y=700
Notion n°10, les « exceptions » (1) Notion n°10, les « exceptions » (2)
●
Il est possible de récupérer le contrôle de l'exécution
lorsqu'une situation d'erreur ou exceptionnelle survient
●
Il est possible de récupérer le contrôle de l'exécution
lorsqu'une situation d'erreur ou exceptionnelle survient
– Division par zéro, conversion de type impossible, accès à un indice
inexistant (listes, n-uplets) ou à une clef inexistante (dictionnaires),
●
Exemple n°1 (ValueError) :
tentative d'affectation d'une structure non mutable (tuple, chaîne),
ouverture d'un fichier non existant ou sans droits suffisants,... try:
s = input("Quel entier svp ? ") # s est une chaîne de caractères
– Si tout se passe bien, les actions « de rattrapage » sont ignorées i = int(s) # conversion string → int
except: # exception « ValueError »
– Si quelque chose tourne mal (une « exception est soulevée »), alors les print("Désolé mais %s n'est pas un entier !" % s)
actions de rattrapage (ou de secours) sont exécutées
i = 42 # cette valeur conviendra !
●
Syntaxe simplifiée : ●
Exemple n°2 (IndexError) :
Actions ordinaires,
try: pouvant « soulever » une excéption try:
i = int(input("Quel indice d'étudiant ? ")) # danger conversion !
ACTIONS1 e = ETUDIANTS[i] # danger accès !
Actions extraordinaires (de rattrapage),
except: exécutées seulement si une excéption est soulevée except: # ValueError ou IndexError
dans les ACTIONS1 e = ETUDIANTS[0] # le premier conviendra !
ACTIONS2
5 6
Notion n°10, les « exceptions » (3) Notion n°10, les « exceptions » (4)
●
En Python, comme dans d'autres langages, les exceptions
●
Il est possible de récupérer le contrôle de l'exécution lorsqu'une correspondent à des valeurs qui précisent la nature de l'erreur
situation d'erreur ou exceptionnelle survient
Value_error, Index_error, EOFError, ZeroDivisionError, IOError,...
●
Exemple n°3 (différencier les exceptions) :
●
Syntaxe générale : Actions ordinaires,
def choix_etudiant(ETUDIANTS): pouvant « soulever » une excéption
try: try:
i = int(input("Quel indice d'étudiant ? ")) # danger conversion !
ACTIONS0
e = ETUDIANTS[i] # danger accès !
return(e) [except EXPR1: ACTIONS1] Actions extraordinaires (de rattrapage) : les ACTIONSi
except ValueError:
... sont exécutées seulement si une excéption est soulevée
print("L'indice doit être un nombre entier !")
[except EXPRn: ACTIONSn] dans ACTIONS0 et si l'expression EXPRi correspond
return (choix_etudiant(ETUDIANTS)) # appel récursif
except IndexError: à l'exception soulevée
[except: ACTIONSn+1]
n = len(ETUDIANTS)
print("L'indice doit être un nombre entre 0 et %d !" % (n-1))
return (choix_etudiant(ETUDIANTS)) # appel récursif Remarque : pour regrouper le traitement de plusieurs exceptions à la fois,
except: les expressions EXPRi après le mot clef except pourront aussi être
return (ETUDIANTS[0]) # le premier conviendra pour tous les autres cas!
7 8
des n-uplets d'exceptions, par exemple (Value_error, Index_error)
Notion n°10, les « exceptions » (5) Notion n°11 : La vérité sur le stockage des variables
Environnement, Mémoire, Adresses, Pointeurs (1)
●
En Python, comme dans d'autres langages, les exceptions
correspondent à des valeurs qui précisent la nature de l'erreur ●
Souvenirs du premier cours :
Value_error, Index_error, EOFError, ZeroDivisionError, IOError,...
– Pour traiter l'information que le programmeur connaît mais surtout celle qu'il
●
Il existe aussi une instruction, qui s'appelle raise, qui permet de ne connaît pas, les langages de programmation proposent les « variables »
soulever manuellement une exception – Les variables sont des boîtes qui ont un nom et un contenu
●
Syntaxe TOTO = "salut le monde"
Expression d'exception Y = 16
raise EXPR X = 3.14159
– Le contenu est une valeur, c'est-à-dire une information traitée par le langage
●
Exemple (regrouper plusieurs types d'erreur) :
de programmation
def choix_etudiant(ETUDIANTS):
try: ●
Ce n'est pas faux, juste un peu simpliste...
i = int(input("Quel indice d'étudiant ? ")) # danger conversion !
e = ETUDIANTS[i] # danger accès !
– La réalité est un peu plus complexe : il existe une mémoire qui permet de
return e stocker une valeur à une certaine adresse, et un catalogue des noms
except: (environnement) qui donne les adresses des valeurs associées
raise Value_error # une seule exception, peut-être rattrapée ailleurs...
9 10
Notion n°11 : La vérité sur le stockage des variables Notion n°11 : La vérité sur le stockage des variables
Environnement, Mémoire, Adresses, Pointeurs (2) Environnement, Mémoire, Adresses, Pointeurs (3)
●
Il existe une mémoire qui permet de stocker une valeur à une certaine adresse, et ●
Pour comprendre ce que sont les pointeurs, supposons de faire l'affectation
un catalogue des noms (environnement) qui donne les adresses des valeurs suivante :
associées LISTE = [TOTO, Y, X]
CATALOGUE des noms MEMOIRE
CATALOGUE des noms MEMOIRE
(ENVIRONNEMENT) adresse contenu (ENVIRONNEMENT) adresse contenu
nom adresse
nom adresse 0x1313d40 0x1313d40
"salut le monde" TOTO 0x1313d40 "salut le monde"
TOTO 0x1313d40
Y 0x1753db8
Y 0x1753db8
X 0x1953ab2
X 0x1953ab2
LISTE 0x18010ce 0x1753db8
16
0x1753db8 16 Remarque :
Il y a des noms,
tels que TOTO, Y, X, LISTE
Remarque : et des sous-noms,
0x18010ce [0] [1] [2] LISTE
Les « boîtes » ou « box » (emplacements) tels que LISTE[0], LISTE[1], LISTE[2]
(trois sous-boîtes)
en mémoire peuvent être de tailles Et il y a donc : 0x1313d40 0x1753db8 0x1953ab2
différentes (en nombre d'octets) des adresses (de noms) stockées dans l'environnement
des adresses (de sous-noms) stockées dans la mémoire.
Notion n°11 : La vérité sur le stockage des variables Notion n°12 : La vérité sur l'appel de fonction :
Environnement, Mémoire, Adresses, Pointeurs (6) Environnement global et local (1)
●
En Python, l'unique affectation qui existe est une création ou mise-à-jour de ●
Souvenirs du deuxième cours :
référence :
REFERENCE = EXPR – Syntaxe de définition (abstraction) d'une fonction :
(1) L'évaluation de EXPR donne une adresse a où se trouve le résultat v
def NOM (ARG1, … ,ARGn): ENVIRONNEMENT ENVIRONNEMENT
(2) La référence est associée maintenant à l'adresse a GLOBAL LOCAL
ACTIONS
MEMOIRE nom adresse nom adresse
●
Exemple (la réf. est un sous-nom) 0x1313d40 – Syntaxe d'appel (application) : TOTO 0x1313d40 Z 0x2255e90
"salut le monde" Y 0x1753db8 X 0x2258faa
Y = Y * 2
NOM (EXPR1, … ,EXPRn) X 0x1953ab2
LISTE[2] = TOTO # sous-nom
0x1753db8 Emplacement
16 recyclable ? ●
Au moment de l'appel, un environnement local est créé pour être utilisé
CATALOGUE des noms
(ENVIRONNEMENT) 0x18000ab
pendant l'exécution de la fonction (il sera éliminé à la fin)
32
nom adresse – Il est prioritaire par rapport à l'environnement global : en écriture, les
TOTO 0x1313d40 0x18010ce [0] [1] [2] LISTE affectations concernent l'environnement local ; en lecture, on cherche avant
0x1953ab2 (trois sous-boîtes) dans le local, puis dans le global (ce qui résout le problème des homonymes)
Y 0x1753db8 0x1313d40 0x1753db8 0x1313d40
Y 0x18000ab Emplacement
– En premier lieu, pour commencer l'appel, sont exécutés les
recyclable ? affectations :
X 0x1953ab2
0x1953ab2 15 16
LISTE 0x18010ce 3.14159 ARG1=EXPR1; … ; ARGn= EXPRn;
Notion n°12 : La vérité sur l'appel de fonction : Notion n°12 : La vérité sur l'appel de fonction :
Environnement global et local (2) Environnement global et local (3)
●
Que se passe t'il lorsqu'on fait appel à une fonction qui fait des affectations ●
Que se passe t'il lorsqu'on fait appel à une fonction qui fait des affectations
(dans ACTIONS) ? Est-ce que l'effet est visible à l'extérieur de la fonction ? (dans ACTIONS) ? Est-ce que l'effet est visible à l'extérieur de la fonction ?
def foo(Z): Z=[] # remet la liste à vide def foo(Z): Z=[]
def bar(X): X[0]=0 # (X homonyme) remet à zero le premier élément de la liste def bar(X): X[0]=0
MEMOIRE
TOTO = "salut le monde" foo(LISTE) # LISTE ne change pas 0x1313d40
ENVIRONNEMENT ENVIRONNEMENT "salut le monde"
GLOBAL LOCAL bar(LISTE) # LISTE devient [0, 16, 3.14159]
Y = 16 Pour foo(LISTE)
nom adresse
TOTO 0x1313d40 nom adresse
X = 3.14159 0x1753db8 16
Z 0x18010ce ENVIRONNEMENT
Y 0x1753db8
LOCAL
LISTE = [TOTO, Y, X] X 0x1953ab2 Résultat de l'affectation Pour foo(LISTE)
préliminaire Z = LISTE ENVIRONNEMENT 0x1800feb 0
LISTE 0x18010ce GLOBAL nom adresse
foo(LISTE)
nom adresse Z 0x18010ce
0x1907ace
print(LISTE) # affiche ['salut le monde', 16, 3.14159] TOTO 0x1313d40 0x18010ce [0] [1] [2]
0x1313d40
Y 0x1753db8 0x1800feb 0x1753db8 0x1953ab2
bar(LISTE) ENVIRONNEMENT
LOCAL X 0x1953ab2
ENVIRONNEMENT
print(LISTE) # affiche [0, 16, 3.14159] Pour bar(LISTE) LISTE 0x18010ce LOCAL
Pour bar(LISTE) 0x1907ace []
nom adresse
X 0x18010ce nom adresse 0x1953ab2
●
Pourquoi 0 ? 17 X 0x18010ce
3.14159 18
Résultat de l'affectation
préliminaire X = LISTE