Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Licence CC BY-NC-ND Thierry Parmentelat & Arnaud Legout Inria - UCA

Complément - niveau intermédiaire

L’instruction try est généralement assortie d’une une ou plusieurs clauses except, comme on l’a vu dans la vidéo.

Sachez que l’on peut aussi utiliser - après toutes les clauses except :

Voyons cela sur des exemples.

finally

C’est sans doute finally qui est la plus utile de ces deux clauses, car elle permet de faire un nettoyage dans tous les cas de figure - de ce point de vue, cela rappelle un peu les context managers.

Et par exemple, comme avec les context managers, une fonction peut faire des choses même après un return.

# une fonction qui fait des choses après un return
def return_with_finally(number):
    try:
        return 1/number
    except ZeroDivisionError as e:
        print(f"OOPS, {type(e)}, {e}")
        return("zero-divide")
    finally:
        print("on passe ici même si on a vu un return")
# sans exception
return_with_finally(1)
on passe ici même si on a vu un return
1.0
# avec exception
return_with_finally(0)
OOPS, <class 'ZeroDivisionError'>, division by zero
on passe ici même si on a vu un return
'zero-divide'

else

La logique ici est assez similaire, sauf que le code du else n’est exécuté que dans le cas où aucune exception n’est attrapée.

En première approximation, on pourrait penser que c’est équivalent de mettre du code dans la clause else ou à la fin de la clause try. En fait il y a une différence subtile :

The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the tryexcept statement.

Dit autrement, si le code dans la clause else lève une exception, celle-ci ne sera pas attrapée par le try courant, et sera donc propagée.

Voici un exemple rapide, en pratique on rencontre assez peu souvent une clause else dans un try :

# pour montrer la clause else dans un usage banal
def function_with_else(number):
    try:
        x = 1/number
    except ZeroDivisionError as e:
        print(f"OOPS, {type(e)}, {e}")
    else:
        print("on passe ici seulement avec un nombre non nul")
    return 'something else'
# sans exception
function_with_else(1)
on passe ici seulement avec un nombre non nul
'something else'
# avec exception
function_with_else(0)
OOPS, <class 'ZeroDivisionError'>, division by zero
'something else'

Remarquez que else ne présente pas cette particularité de “traverser” le return, que l’on a vue avec finally :

# la clause else ne traverse pas les return
def return_with_else(number):
    try:
        return 1/number
    except ZeroDivisionError as e:
        print(f"OOPS, {type(e)}, {e}")
        return("zero-divide")
    else:
        print("on ne passe jamais ici à cause des return")
# sans exception
return_with_else(1)
1.0
# avec exception
return_with_else(0)
OOPS, <class 'ZeroDivisionError'>, division by zero
'zero-divide'

Pour en savoir plus

Voyez le tutorial sur les exceptions dans la documentation officielle.