質問

次のコードでは、構文エラーが発生します。

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

重要な場合は、Python 2.6.6を使用しています。

役に立ちましたか?

解決

の用法 継続する 最終的には、その解釈が問題になっていたため、最終的には禁止されています。例外のために最終的な条項が実行されていた場合、あなたはどうしますか?

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

このコードが何をすべきかを決定することができます。おそらく例外を飲み込んでいます。しかし、良い言語デザインはそうでないことを示唆しています。コードが読者を混同している場合、または意図したロジックを表現する明確な方法がある場合(おそらく try: ... except Exception: pass; continue)、それからこれを残すことにはいくつかの利点があります 構文エラー.

興味深いことに、aを置くことができます 戻る 最終的な条件の中で、それは keyboardinterrupt, SystemExit, 、 と メモリエラー. 。それはおそらく良い考えでもありません;-)

他のヒント

Python言語リファレンス の使用を禁止します continue 以内 finally 句。理由は完全にはわかりません。おそらく continue 以内 try 節は、を保証します finally 実行され、何を決定します continue 内で行う必要があります finally 節はやや曖昧です。

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

継続的な声明は、実装の問題のために最終条項で違法でした。 Python 3.8では、この制限が解除されました。

バグはそうでした Issue32489-「最後に」句で「続行」を許可する.

修正のプル要求: https://github.com/python/cpython/pull/5822

この理由は実際には非常に簡単だと思います。最終的なキーワードが毎回実行された後の続行ステートメント。それが最終的な声明の性質です。コードが例外をスローするかどうかは無関係です。最後に実行されます。

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

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は、続行後のすべてのコードが実行されないため、最終的なブロックでの継続を許可しません。 (スパースは濃いよりも優れています。)

私はそれが別の応答で言及されているのを見ませんでしたが、この場合にあなたが望むかもしれないものは 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. 私達 trydo_something_that_might_fail(i)
  3. それが投げる場合 SomeException, 、倒れて print i また
  4. そうでなければ、私たち continue (と i 印刷されることはありません)

例外を提起する可能性は、あなたが使用しているので飲み込んだだけです continue は強い議論ですが、例外も使用すると飲み込まれます break また return 代わりは。

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

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

なぜそうなるのでしょうか breakreturn で許可されます finally エラーが発生する有無にかかわらずブロックしますが、 continue いいえ?

また、問題の次の要因の組み合わせを考慮することもできます。

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

これは、各ループの内部を意味します。 finally 常に実行して、あなたは常に持っています continue 魔女は基本的に「現在のイテレーションを中止」、「電流のイテレーションを中止する」、「電流のイテレーションを中止する」と言っています...魔女は本当に意味がありません。しかし、使用することも意味がありません breakreturn. 。また、現在の反復は、1つの反復だけで終わる唯一の違いで中止されています。

だから、「なぜそうなのか」という質問 continue で許可されていません finally?」とも尋ねることができます」 breakreturn 許可された?"。

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

アイデアはそれです ここの例は極端です. 。あなたはそのようなコードを書くだけではありませんか?いくつかのロジックがあるはずです finally いつ言うかをブロックします break/return/continue, 、何でも、そのように鈍いだけではありません。そのため、私見 continue 内側 finally 使用してきれいなコードを書くことに感謝しているので、許可する必要があります continuefinally それが私が必要なものである場合、この制限のためにコードの回避策に頼る代わりに(つまり、Pythonの哲学では「私たちはすべてここで大人に同意している」)。

これで、この機能は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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top