43

次のコードは構文エラーを発生させます:

>>> for i in range(10):
...     print i
...     try:
...        pass
...     finally:
...        continue
...     print i
...
  File "<stdin>", line 6
SyntaxError: 'continue' not supported inside 'finally' clause

continue内でステートメントが許可されないのはなぜですか?finally

PS一方、この他のコードには問題はありません。

>>> for i in range(10):
...     print i
...     try:
...        pass
...     finally:
...        break
...
0

重要な場合は、Python2.6.6を使用しています。

4

7 に答える 7

27

解釈に問題があったため、finally節でcontinueを使用することは禁止されています。例外のためにfinally節が実行された場合はどうしますか?

for i in range(10):
    print i
    try:
       raise RuntimeError
    finally:
       continue        # if the loop continues, what would happen to the exception?
    print i

おそらく例外を飲み込んで、このコードが何をすべきかについて決定を下すことが可能です。しかし、優れた言語設計はそうではないことを示唆しています。コードが読者を混乱させる場合、または意図したロジックを表現するためのより明確な方法がある場合(おそらく)、これをSyntaxErrortry: ... except Exception: pass; continueとして残すことにはいくつかの利点があります。

興味深いことに、finally句の中にreturnを入れると、 KeyboardInterruptSystemExitMemoryErrorなどのすべての例外が飲み込まれます。それもおそらく良い考えではありません;-)

于 2011-11-28T21:30:31.103 に答える
6

Python言語リファレンスでは、句内での使用は禁止されています。continuefinally理由はよくわかりません。おそらく、句continue内でが実行されるtryことを保証し、句内で何をすべきかを決定することはやや曖昧だからです。finallycontinuefinally

編集:質問に対する@Mike Christensenのコメントは、この構造のあいまいさがPythonコア開発者によって議論されているスレッドを指摘しています。さらに、Pythonを9年以上使用してきたので、これをやりたくなかったので、開発者があまり時間をかけたくないというのは、おそらく比較的まれな状況です。

于 2011-11-28T21:17:57.393 に答える
5

実装に問題があるため、finally句のcontinueステートメントは不正でした。Python 3.8では、この制限が解除されました。

バグはissue32489でした​​-「finally」句で「continue」を許可します。

修正のプルリクエスト:https ://github.com/python/cpython/pull/5822

于 2018-04-20T05:27:19.170 に答える
2

私はそれが別の応答で言及されているのを見ませんでしたが、この場合あなたが望むかもしれないものはtry..else

for i in range(10):
    print i
    try:
       #pass <= I commented this out!
       do_something_that_might_fail(i)
    except SomeException:
       pass
    else:
       continue
    print i

ブロックは、else例外がなかった場合にのみ実行されます。つまり、これは次のことを意味します。

  1. 我々print i
  2. tryたちdo_something_that_might_fail(i)
  3. スローした場合は、何度もSomeException失敗しますprint i
  4. そうでなければ、私たちはcontinue(そしてi決して印刷されません)
于 2011-11-29T19:55:08.570 に答える
2

その理由は実はかなり単純だと思います。finallyキーワードの後のcontinueステートメントは毎回実行されます。それがfinallyステートメントの性質です。コードが例外をスローするかどうかは関係ありません。最後に実行されます。

したがって、あなたのコードは...

for i in range(10):
   print i
   try:
       pass
   finally:
       continue
   print i # this (and anything else below the continue) won't ever be executed!

このコードと同等です...

for i in range(10:
    print i
    try:
        pass
    finally:
        pass

これはよりクリーンで簡潔です。継続後のすべてのコードが実行されることはないため、Pythonはfinallyブロックでの継続を許可しません。(スパースはデンスよりも優れています。)

于 2011-11-29T02:02:21.877 に答える
2

を使用しているために例外が発生してから飲み込まれる可能性は強力な議論ですが、またはの代わりcontinueにを使用すると例外も飲み込まれます。breakreturn

たとえば、これは機能し、例外は飲み込まれます。

for i in range(10):
    print i
    try:
        raise Exception
    finally:
        break
    print i       # not gonna happen

これもエラーなしで機能し(関数内の場合)、例外も飲み込まれます。

for i in range(10):
    print i
    try:
        raise Exception
    finally:
        return
    print i       # not gonna happen

では、発生する可能性のあるエラーの有無にかかわらず、なぜブロック内で許可されるのbreakでしょうか。returnfinallycontinue

この問題では、次の要素の組み合わせを検討することもできます。

  • finally常に実行されます。
  • continue現在の反復を「中止」します。

これは、各ループ内で、finally常に実行されているため、常にcontinue魔女が「現在の反復を中止」、「現在の反復を中止」、「現在の反復を中止」と言うことを意味します...魔女は実際には意味がありません。breakしかし、とを使用することも意味がありませんreturn。現在の反復も中止されますが、唯一の違いは、1回の反復で終わることです。

それで、「なぜcontinue許可されないのfinallyですか?」という質問があります。「なぜ許可されているのか」breakと尋ねることもできます。return

たぶん、その時点でそうしないことが理にかなっているからですか?それは開発者の決定でしたが、今はそうですか?確かに、それは実装者の怠惰かもしれませんが、おそらく彼らは何かを念頭に置いていたのかもしれませんし、Pythonの別のバージョンでは、別の方法でそれを持っている方が理にかなっていますか?

ここでの例は極端なものであるという考え方です。そのようなコードを書くだけではありませんか?finallyブロックには、いつ、何でも言うためのロジックが必ずあり、break/return/continueそのように鈍くするだけではありません。そのため、この制限のコード回避策にcontinue頼るのではなく、必要に応じてinfinallyを使用してクリーンなコードを記述していただければ幸いです(つまり、Pythonの哲学では「私たちはすべてここで大人に同意しています」 )。continuefinally

于 2011-11-30T21:50:09.490 に答える
-1

現在、この機能は3.8のリリースで利用可能です

https://docs.python.org/3/whatsnew/3.8.html

サンプルコード

def new_f():
    for i in range(0,24):
        try:
            print(1/0)
        except:
            print('In Exception')
        finally:
            print('In finally')
            continue
于 2019-10-19T12:11:10.237 に答える