Il y a le code intéressant ci-dessous:
def func1():
try:
return 1
finally:
return 2
def func2():
try:
raise ValueError()
except:
return 1
finally:
return 3
func1()
func2()
Quelqu'un pourrait-il expliquer, quels résultats renverront ces deux fonctions et expliquer pourquoi, c.-à-d. Décrire l’ordre d’exécution
De la Python documentation
Une clause finally est toujours exécutée avant de quitter l'instruction try, qu'une exception soit survenue ou non. Lorsqu'une exception s'est produite dans la clause try et qu'elle n'a pas été gérée par une clause except (ou qu'elle s'est produite dans une clause except ou else), elle est à nouveau déclenchée après l'exécution de la clause finally. La clause finally est également exécutée "à la sortie" lorsqu'une autre clause de l'instruction try est laissée via une instruction break, continue ou return . Un exemple plus compliqué (avoir les clauses except et finally dans la même instruction try fonctionne à partir de Python 2.5):
Donc, une fois que le bloc try/except est quitté, utilisez return , ce qui définirait la valeur de retour comme étant donné - les blocs finiront par toujours exécuter, et devrait être utilisé pour libérer des ressources, etc. tout en utilisant un autre retour - écrase le premier.
Dans votre cas particulier, func1()
return 2
Et func2()
return 3
, Car il s'agit de valeurs renvoyées dans les blocs finally.
Il ira toujours dans le bloc finally
, donc il ignorera le return
dans les try
et except
. Si vous aviez return
au-dessus de try
et except
, il renverrait cette valeur.
def func1():
try:
return 1 # ignoring the return
finally:
return 2 # returns this return
def func2():
try:
raise ValueError()
except:
# is going to this exception block, but ignores the return because it needs to go to the finally
return 1
finally:
return 3
def func3():
return 0 # finds a return here, before the try except and finally block, so it will use this return
try:
raise ValueError()
except:
return 1
finally:
return 3
func1() # returns 2
func2() # returns 3
func3() # returns 0
Mettre les déclarations print
à l'avance aide vraiment, aide vraiment:
def func1():
try:
print 'try statement in func1. after this return 1'
return 1
finally:
print 'after the try statement in func1, return 2'
return 2
def func2():
try:
print 'raise a value error'
raise ValueError()
except:
print 'an error has been raised! return 1!'
return 1
finally:
print 'okay after all that let\'s return 3'
return 3
print func1()
print func2()
Cela retourne:
try statement in func1. after this return 1
after the try statement in func1, return 2
2
raise a value error
an error has been raised! return 1!
okay after all that let's return 3
3
Vous remarquerez que python renvoie toujours la dernière chose à retourner, même si le code "atteint" return 1
dans les deux fonctions.
Un bloc finally
est toujours exécuté, la dernière chose à renvoyer dans la fonction est donc ce qui est retourné dans le bloc finally. Dans func1
, ça fait 2. Dans func2
, c'est 3.
func1()
renvoie 2. func2()
renvoie 3.
finally
le bloc est exécuté finalement quelle que soit l'exception.
Vous pouvez voir l'ordre d'exécution à l'aide du débogueur. Par exemple, voir n screencast .