devstory

Le Tutoriel de gestion des exceptions Python

  1. Qu'est- ce que Exception?
  2. La hiérarchie des exceptions
  3. Gestion de l'exception avec try-except
  4. Le bloc try-except-finally
  5. Relancer l'exception
  6. Emballage une Exception dans une autre Exception

1. Qu'est- ce que Exception?

Tout d'abord, voyons l'exemple d'illustration suivant:
Dans cet exemple, il existe une partie du code d'erreur qui résulte de la division par 0. La division par 0 provoque l'exception: ZeroDivisionError
helloExceptionExample.py
print ("Three")

# Cette division a aucun problème.
value = 10 / 2 
print ("Two")

# Cette division a aucun problème.
value = 10 / 1 
print ("One")

d = 0

# Cette division a un problème, divisé par 0.
# Une erreur s'est produite ici.
# ​​​​​​​
value = 10 / d

# Et le code suivant ne sera pas exécuté.
print ("Let's go!")
Le résultat de l'exécution de l'exemple:
Vous pouvez voir la notification sur l'écran de la console. La notification d'erreur est très claire, y compris les informations de la ligne de code.
Voyons le flux du programme à travers l'illustration suivante.
  • Le programme s'exécute normalement de l'étape (1),(2) à (6)
  • À l'étape (7), le programme est divisé par 0. Le programme se termine.
  • Et l'étape (8), le code n'a pas été exécuté.
Nous modifierons le code de l'exemple ci-dessus.
helloCatchException.py
print ("Three")

value = 10 / 2

print ("Two")

value = 10 / 1
 
print ("One")

d = 0 

try :
    # Cette division a un problème, divisé par 0.
    # Une erreur s'est produite ici (ZeroDivisionError).
    value = 10 / d 
    print ("value = ", value) 
except ZeroDivisionError as e : 
    print ("Error: ", str(e) )
    print ("Ignore to continue ...") 

print ("Let's go!")
Et les résultats de l'exécution de l'exemple :
Three
Two
One
Error division by zero
Ignore to coninue ...
Let's go!
Nous allons expliquer le flux du programme par les images d'illustration suivantes.
  • Des étapes (1)-(6) sont complètement normales.
  • L'exception se produit à l'étape (7), le problème a divisé par 0.
  • Tout de suite, il effectue l'exécution de la commande dans le bloc except, l'étape (8) est omise.
  • L'étape (9), (10) sont exécutées.
  • L'étape (11) est exécutée.

2. La hiérarchie des exceptions

This is the model of hierarchical map of Exception in Python.
  • La classe la plus élevée est BaseException
  • Les sous-classes directes sont ExceptionKeyboardInterrupt, ...

Les Exception disponibles en Python qui sont normalement dérivées (derived) de BaseException (Étendues de BaseException). Alors que les exceptions de l’utilisateur (du programmeur) devrient hériter ses Exception ou de ses sous-classes.

3. Gestion de l'exception avec try-except

Nous écrivons une classe qui hérite de la classe Exception.
La fonction checkAge sert à vérifier l'âge, si l'âge est moins de 18 ou plus de 40, une exception se produira.
ageexception.py
# Python 3.x 
class AgeException(Exception): 
    def __init__(self, msg, age ):
        super().__init__(msg) 
        self.age = age 
        
class TooYoungException(AgeException): 
    def __init__(self, msg, age):
        super().__init__(msg, age)     

class TooOldException(AgeException): 
    def __init__(self, msg, age):
        super().__init__(msg, age)    
         
# La fonction de vérifier l'âge, il peut lever l'exception..
def checkAge(age): 
    if (age < 18) :
        # Si l'âge est inférieur à 18 ans, une exception sera levée.
        # Cette fonction se termine ici.
        raise TooYoungException("Age " + str(age) + " too young", age) 
    elif (age > 40) :
        # Si l'âge est supérieur à 40, une exception sera levée.
        # Cette fonction se termine ici.        
        raise TooOldException("Age " +  str(age) + " too old", age); 
    # Si l'âge est entre 18-40.
    # Ce code sera exécuté.
    print ("Age " +  str(age) + " OK!");
Exemple:
tryExceptDemo1.py
import ageexception
from ageexception import AgeException
from ageexception import TooYoungException
from ageexception import TooOldException

print ("Start Recruiting ...")
age = 11
print ("Check your Age ", age)
try : 
    ageexception.checkAge(age)
    print ("You pass!")  
except TooYoungException as e  : 
    print("You are too young, not pass!")    
    print("Cause message: ", str(e) )
    print("Invalid age: ", e.age) 
except  TooOldException as e : 
    print ("You are too old, not pass!")
    print ("Cause message: ", str(e) )
    print("Invalid age: ", e.age)
Exécutez l'exemple:
Start Recruiting ...
Check you Age 11
You are too young, not pass!
Cause message: Age 11 too young
Invalid age: 11
Dans l'exemple ci-dessous, nous allons intercepter les exceptions par les exceptions parentales. Au niveau plus supérieur, elle attrapera des exceptions et tous les sous-exceptions.
tryExceptDemo2.py
import ageexception
from ageexception import AgeException
from ageexception import TooYoungException
from ageexception import TooOldException

print ("Start Recruiting ...")
age = 51 
print ("Check your Age ", age)
try : 
    ageexception.checkAge(age)
    print ("You pass!") 
except AgeException as e  : 
    print("You are not pass!")  
    print("type(e): ", type(e) )
    print("Cause message: ", str(e) )
    print("Invalid age: ", e.age)
Output:
Start Recruiting ...
Check you Age 51
You are not pass!
type(e): <class 'ageexceptioon.TooOldException'>
Cause message: Age 51 too old
Invalid age: 51

4. Le bloc try-except-finally

Nous nous sommes habitués à attraper l'erreur via le bloc try-except. La gestion des exception complète est try-except-finally. Le bloc finally est toujours exécuté, que l'exception se produise ou non dans le bloc try.
try - except - finally
try : 
    # Faites quelque chose ici.
except Exception1 as e : 
    # Faites quelque chose ici.
except Exception2 as e : 
    # Faites quelque chose ici.
finally : 
    # Le bloc finally est toujours exécuté.
    # Faites quelque chose ici.
Exemple:
tryExceptFinallyDemo.py
def toInteger(text) : 
    try :  
        print ("-- Begin parse text: ", text) 
        # Une exception peut lancer ici (ValueError).
        value = int(text) 
        return value 
    except ValueError as e : 
        # Dans le cas de 'texte' n'est pas un nombre.
        # Ce bloc 'except' sera exécuté.
        print ("ValueError message: ", str(e))
        print ("type(e): ", type(e)) 
        # Renvoie 0 si ValueError se produit.
        return 0  
    finally :  
        print ("-- End parse text: " + text)  
 
text = "001234A2" 
value = toInteger(text) 
print ("Value= ", value)
Exécution de l'exemple:
-- Begin parse text: 001234A2
ValueError message: invalid literal for int() with base 10: '001234A2'
type(e): <class 'ValueError'>
-- End parse text: 001234A2
Value= 0
Voici est le flux du programme. Le bloc finally est toujours exécuté.
La commande pass
Si vous ne voulez rien traiter dans le bloc 'except' ou 'finally', vous pouvez utiliser l'instruction 'pass' (pass statement). La commande passe ne fait rien, c'est comme une déclaration nulle.
passStatementExample.py
print ("Three")
try :
    value = 10 / 0;
except Exception as e:
    pass

print ("Two")  
print ("One")
print ("Let's go")
Output:
Three
Two
One
Let's go

5. Relancer l'exception

Lors de la gestion de l'exception, vous pouvez attraper cette exception et la gérer ou vous pouvez la relancer (rethrow).
reRaiseExceptionDemo1.py
def checkScore(score) :
    if score < 0 or score > 100:
        raise Exception("Invalid Score " + str(score) )

def checkPlayer(name, score):
    try :
        checkScore(score)
    except Exception as e :
        print ("Something invalid with player: ",name, ' >> ', str(e) )
        # re throw exception.
        raise   
# ------------------------------------------ 
checkPlayer("Tran", 101)
Par exemple, attrapez une exception et jettez (rethrow) une autre exception.
reRaiseExceptionDemo2.py
def checkScore(score) :  
    if score < 0 or score > 100:
        raise Exception("Invalid Score " + str(score) )

def checkPlayer(name, score):
    try :
        checkScore(score)
    except Exception as e :
        print ("Something invalid with player: ",name, ' >> ', str(e) )
        # throw new exception.
        raise Exception("Something invalid with player: "+ name + " >> "+ str(e)) 

# ------------------------------------------ 
checkPlayer("Tran", 101)

6. Emballage une Exception dans une autre Exception

Python permet d'attraper et de jeter une nouvelle exception. Des nouvelles exceptions peuvent stocker des informations de l'exception originale que vous avez accédé via l'attribut __cause__.
Syntax
try : 
    # Faites quelque chose ici ...
except Exception as e : 
    raise OtherException("Message...") from e
Voyons l'exemple complet:
wrapExceptionDemo.py
# Python 3.x:
# L'exception de genre
class GenderException(Exception): 
    def __init__(self, msg):
        super().__init__(msg)     

# L'exception linguistique.
class LanguageException(Exception): 
    def __init__(self, msg):
        super().__init__(msg)     


class PersonException(Exception): 
    def __init__(self, msg):
        super().__init__(msg)

# Cette fonction peut lancer GenderException.
def checkGender(gender): 
    if gender != 'Female' :
        raise GenderException("Accept female only")

# Cette fonction peut lancer LanguageException.
def checkLanguage(language):   
    if language != 'English' :
        raise LanguageException("Accept english language only") 

def checkPerson(name, gender, language): 
    try : 
        # Peut lancer GenderException.
        checkGender(gender)
        # Peut lancer LanguageException.
        checkLanguage(language)
    except Exception as e:
        # Attraper l'exception et lever une autre exception.
        # La nouvelle exception a __cause__ = e.
        raise PersonException(name + " does not pass") from e
    
# -------------------------------------------------------- 
try  : 
    checkPerson("Nguyen", "Female", "Vietnamese") 
except PersonException as e: 
    print ("Error message: ", str(e) )    
    # GenderException ou LanguageException
    cause = e.__cause__   
    print ('e.__cause__: ', repr(cause)) 
    print ("type(cause): " , type(cause) ) 
    print (" ------------------ ")
    
    if type(cause) is GenderException : 
        print ("Gender exception: ", cause) 
    elif type(cause) is LanguageException: 
        print ("Language exception: ", cause)
Output:
Error message: Nguyen does not pass
e.__cause__: LanguageException('Accept english language only',)
type(cause): <class '__main__.LanguageException'>
 ------------------
Language exception: Accept english language only