3

tryエラー処理のためにandを使用するexcept場合、明示的に呼び出すfinallyか、単に例外コードから離れた新しい行に移動するかは重要ですか? たとえば、以下の 2 つの関数が異なる結果を生成する状況はありますか?

#Function 1 with finally
def final(x):
    try:
        print(x*x)

    except:
        print("Error")

    finally:
        print("End Function")


#Function 2 with new line dedent
def dedent(x):
    try:
        print(x*x)

    except:
        print("Error")

    print("End Function")

更新:ブロックfinallyにエラーがあっても実行 するという説明をありがとう。exceptもう 1 つ指摘しておきたいのはfinally、except ブロック内でオブジェクトを返しても、ブロックは実行されるということです。たとえば、次の関数 3 は出力されますが、return関数 4 は出力されません。

#Function 3 with finally
def final(x):
    try:
        print(x*x)

    except:
        return 3

    finally:
        print("End Function 3")


#Function 4 with new line dedent
def dedent(x):
    try:
        print(x*x)

    except:
        return 3

    print("End Function 4")

test1 = final('test')
test2 = dedent('test')
4

4 に答える 4

3

exceptすでに言及されているブロックにエラーがあります:

def final(x):
    try:
        print(x*x)

    except:
        print("Error")
        damnit

    finally:
        print("End Function")

def dedent(x):
    try:
        print(x*x)

    except:
        print("Error")
        damnit

    print("End Function")

try:
    final("a")
except Exception as e:
    print("There was an error:", e)
#>>> Error
#>>> End Function
#>>> There was an error: global name 'damnit' is not defined

try:
    dedent("a")
except Exception as e:
    print("There was an error:", e)
#>>> Error
#>>> There was an error: global name 'damnit' is not defined

振る舞いもありreturnます:

def final(x):
    try:
        print(x*x)

    except:
        print("Error")
        return "Return inside"

    finally:
        print("End Function")
        return "Return outside"

def dedent(x):
    try:
        print(x*x)

    except:
        print("Error")
        return "Return inside"

    print("End Function")
    return "Return outside"

try:
    final("a")
except Exception as e:
    print("There was an error:", e)
#>>> Error
#>>> End Function
#>>> 'Return outside'

try:
    dedent("a")
except Exception as e:
    print("There was an error:", e)
#>>> Error
#>>> 'Return inside'
于 2013-09-26T21:30:56.860 に答える
1

PEP 341によると:

try:
    block-1 ...
except Exception1:
    handler-1 ...
except Exception2:
    handler-2 ...
else:
    else-block
finally:
    final-block

ブロック 1 のコードが実行されます。コードで例外が発生すると、さまざまな except ブロックがテストされます。例外がクラス Exception1 の場合、handler-1 が実行されます。それ以外の場合、それがクラス Exception2 の場合、handler-2 が実行されます。例外が発生しない場合、else-block が実行されます。

以前に何が起こったとしても、コード ブロックが完了し、発生した例外が処理されると、最終ブロックが実行されます。例外ハンドラーまたは else ブロックでエラーが発生し、新しい例外が発生した場合でも、最終ブロックのコードは引き続き実行されます。

Martjin が言ったように、finally のコードはexcept別のエラーが発生しても実行されます。

于 2013-09-26T21:27:04.723 に答える
1

いたるところで例外が発生した場合、違いは明らかです。

try ブロックのみがエラーを発生させる場合、それらは同じです。

#Function 1 with finally
def final(x):
    try:
        print(x*x)
        raise Exception
    except:
        print("Error")    
    finally:
        print("End Function")


#Function 2 with new line dedent
def dedent(x):
    try:
        print(x*x)
        raise Exception
    except:
        print("Error")    
    print("End Function")

final(10)
dedent(10)

でも。except ブロックでもエラーが発生した場合は、finally ブロックの実行が保証されます。

#Function 1 with finally
def final(x):
    try:
        print(x*x)
        raise Exception
    except:
        print("Error")
        raise Exception
    finally:
        print("This will be printed")

#Function 2 with new line dedent
def dedent(x):
    try:
        print(x*x)
        raise Exception
    except:
        print("Error")
        raise Exception
    print("This will not be printed")
final(10)
dedent(10)
于 2013-09-26T21:31:21.110 に答える
1

ハンドラーが新しい例外を発生させた場合でも、最初のバージョンは引き続きfinally:スイートを実行します。2 番目のバージョンでは、その場合、ファイナルは実行されません。exceptprint()

>>> def print(*args, **kw):
...     if not args or args[0] != 'End Function':
...         raise ValueError("Only print End Function!")
...     __builtins__.print(*args, **kw)
... 
>>> final(0)
End Function
Traceback (most recent call last):
  File "<stdin>", line 3, in final
  File "<stdin>", line 3, in print
ValueError: Only print End Function!

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in final
  File "<stdin>", line 3, in print
ValueError: Only print End Function!
>>> dedent(0)
Traceback (most recent call last):
  File "<stdin>", line 3, in dedent
  File "<stdin>", line 3, in print
ValueError: Only print End Function!

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in dedent
  File "<stdin>", line 3, in print
ValueError: Only print End Function!

最初に出力されるのfinal(0)End Function;であることに注意してください。に対してそのようなテキストは出力されませんdedent(0)

finally:スイートを明示的に実行する必要はありません。で関数を早期に終了したり、 でループを抜けたり、 でループ本体の残りをスキップしたりしても、常に実行されます。returnbreakcontinue

>>> while True:
...     try:
...         print("In an infinite loop?")
...         break
...     finally:
...         print("Executed before the loop ends")
... 
In an infinite loop
Executed before the loop ends

try声明のドキュメントからの引用:

が存在する場合finally、「クリーンアップ」ハンドラを指定します。and句を含め、try句が実行されます。いずれかの句で例外が発生し、処理されない場合、例外は一時的に保存されます。句が実行されます。保存された例外がある場合は、句の最後で再発生します。exceptelsefinallyfinally

, orステートメントが...ステートメントのスイートで実行されるとreturn、句も「途中で」実行されます。</p> breakcontinuetrytryfinallyfinally

于 2013-09-26T21:23:16.930 に答える