web-dev-qa-db-ja.com

Python最後にブロックを返します

以下に興味深いコードがあります。

def func1():
    try:
        return 1
    finally:
        return 2

def func2():
    try:
        raise ValueError()
    except:
        return 1
    finally:
        return 3

func1()
func2()

誰かがこれらの2つの関数を返す結果とその理由、つまり実行の順序を説明してください

53
skybobbi

Python ドキュメント

Finally節は、例外が発生したかどうかにかかわらず、常にtryステートメントを終了する前に実行されます。 try節で例外が発生し、except節で処理されなかった場合(またはexcept節またはelse節で発生した場合)、finally節が実行された後に例外が再発生します。 finally節は、tryステートメントの他の節がbreak、continue、またはreturnステートメントを介して残された場合も「途中で」実行されます。より複雑な例(同じtryステートメントにexcept節とfinally節があると、Python 2.5)のように機能します):

したがって、returnを使用してtry/exceptブロックが終了すると、戻り値が指定された値に設定され、最終的にブロックはalwaysを実行し、別のリターンを使用しながらリソースなどを解放するために使用する必要があります-元のリターンを上書きします。

特定のケースでは、func1()は_2_を返し、func2()は_3_を返します。これらはfinallyブロックで返される値であるためです。

99
lejlot

常にfinallyブロックに移動するため、returnおよびtryexceptは無視されます。 returntryの上にexceptがある場合、その値を返します。

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
29
user1408786

事前にprintステートメントを置くと、本当に役立ちます。

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

これは返します:

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

pythonは、両方の関数でreturn 1に到達したかどうかに関係なく、常に最後に返されるものを返します。

finallyブロックはalways runであるため、関数で最後に返されるのは、finallyブロックで返されるものです。 func1では2です。func2では3です。

7
TerryA

func1()は2を返します。func2()は3を返します。

finallyブロックは、例外に関係なく最終的に実行されます。

デバッガを使用して実行順序を確認できます。たとえば、 スクリーンキャスト を参照してください。

1
falsetru