109

これは、python の "with" ステートメントを try-except ブロックと組み合わせて使用​​する正しい方法ですか?:

try:
    with open("file", "r") as f:
        line = f.readline()
except IOError:
    <whatever>

もしそうなら、物事を行う古い方法を考慮してください:

try:
    f = open("file", "r")
    line = f.readline()
except IOError:
    <whatever>
finally:
    f.close()

ここでの "with" ステートメントの主な利点は、3 行のコードを削除できることですか? この使用例については、私には説得力がないように思えます(ただし、「with」ステートメントには他の用途があることは理解しています)。

編集: 上記の 2 つのコード ブロックの機能は同じですか?

EDIT2:最初のいくつかの回答は、「with」を使用する利点について一般的に語っていますが、ここではわずかな利点のようです。私たちは皆、何年も f.close() を明示的に呼び出してきました (またはそうすべきでした)。ずさんなコーダーが「with」を使用することで恩恵を受けるという利点があると思います。

4

4 に答える 4

152
  1. 指定した 2 つのコード ブロック は同等ではありません
  2. あなたが物事を行う古い方法として説明したコードには重大なバグがあります。ファイルを開くことが失敗した場合、 がバインドされていないfinallyため、句で2番目の例外が発生します。f

同等の古いスタイルのコードは次のようになります。

try:
    f = open("file", "r")
    try:
        line = f.readline()
    finally:
        f.close()
except IOError:
    <whatever>

ご覧のとおり、このwithステートメントにより、エラーが発生しにくくなります。Python の新しいバージョン (2.7、3.1) では、1 つのwithステートメントで複数の式を結合することもできます。例えば:

with open("input", "r") as inp, open("output", "w") as out:
    out.write(inp.read())

それに加えて、私は個人的に、例外をできるだけ早くキャッ​​チするのは悪い習慣だと考えています。これは例外の目的ではありません。失敗する可能性のある IO 関数がより複雑な操作の一部である場合、ほとんどの場合、IOError は操作全体を中止し、外部レベルで処理する必要があります。ステートメントを使用すると、内部レベルでwithこれらすべてのステートメントを取り除くことができます。try...finally

于 2010-09-05T01:20:19.177 に答える
7

ブロックの内容が開かれているファイルオブジェクトのプロパティによって決定される場合、なぜファイルオブジェクトの実装者がブロックfinallyを書き込むものであるべきではないのですか?これはステートメントの利点であり、この特定のインスタンスで3行のコードを節約するだけではありません。finallywith

withそして、はい、あなたが組み合わせた方法はtry-except、ステートメント自体の中で引き起こされた例外的なエラーをブロックopen内で捕らえることができないので、それを行うためのほとんど唯一の方法です。with

于 2010-09-04T11:53:55.570 に答える
1

行を減らすだけであるという「with」ステートメントについて、あなたは間違っていると思います。実際に初期化を行い、ティアダウンを処理します。

あなたの場合、「with」は

  • ファイルを開き、
  • その内容を処理し、
  • 必ず閉じてください。

「with」ステートメントを理解するためのリンクは次のとおりです:http://effbot.org/zone/python-with-statement.htm

編集:はい、「with」の使用法は正しく、両方のコードブロックの機能は同じです。「with」を使用する理由についての質問?それはあなたがそれで得る利益のためです。誤ってf.close()が欠落していることについておっしゃったように。

于 2010-09-04T11:55:02.623 に答える
-6

次のコードのより Pythonic な方法は次のとおりです。

try:
    f = open("file", "r")
    try:
        line = f.readline()
    finally:
        f.close()
except IOError:
    <whatever>

try:
    f = open("file", "r")
except IOError:
    <whatever>
else:
    f.close()
于 2015-10-13T21:21:10.820 に答える