Python essaie enfin de bloquer les retours [dupliquer]

cette question a déjà une réponse ici:

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()

pourrait s'il vous plaît quelqu'un expliquer, ce que les résultats retourneront ces deux fonctions et d'expliquer POURQUOI, c'est à dire décrire l'ordre d'exécution

39
demandé sur skybobbi 2013-11-06 10:39:20
la source

4 ответов

De l'Python documentation

une clause finale est toujours exécutée avant de quitter la déclaration try, qu'une exception se soit produite ou non. Lorsqu'une exception a eu lieu dans la clause try et n'a pas été traitée par une clause d'exception (ou qu'elle a eu lieu dans une clause d'exception ou d'exception), elle est soulevée de nouveau après l'exécution de la clause finale. La clause finale est également exécutée "sur la sortie" lorsqu'une autre clause de la déclaration try est laissée via une pause, Continuer ou retourner la déclaration . Un exemple plus compliqué (ayant des clauses except et finallement dans la même déclaration try fonctionne comme dans Python 2.5):

ainsi , une fois que le bloc try/except est laissé en utilisant return , qui définirait la valeur de retour à donné - enfin les blocs seront toujours exécuter, et devrait être utilisé pour libérer des ressources, etc. alors en utilisant là un autre retour-écrira l'original.

dans votre cas particulier, func1() retour 2 et func2() retour 3 , car ce sont des valeurs retournées dans les blocs fin.

77
répondu lejlot 2015-02-13 19:20:47
la source

il ira toujours au bloc finally, donc il ignorera les retours dans le try en except. Si vous aviez un retour au-dessus de l'essai et sauf, il retournerait 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
23
répondu user1408786 2013-11-06 10:49:37
la source

Mettre print déclarations à l'avance est vraiment, vraiment utile:

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 renvoie:

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, indépendamment du fait que le code" atteint " return 1 dans les deux fonctions.

Un finally bloc toujours , alors la dernière chose à être retourné dans la fonction est tout ce qui est retourné dans le enfin bloc. Dans func1 , ça fait 2. Dans func2 , ça fait 3.

7
répondu TerryA 2013-11-06 10:48:56
la source

func1() renvoie 2. func2() renvoie 3.

finally bloc est exécuté finalement indépendamment ou exception.

vous pouvez voir l'ordre d'exécution en utilisant le débogueur. Par exemple, voir un screencast .

1
répondu falsetru 2013-11-06 10:47:08
la source