26

「with」はインターネットで検索するのに面白い単語であることがわかりました。

Pythonのステートメントをネストすることで何が問題になるか知っている人はいますか?
私が書いているスクリプトの非常に滑りやすいバグを追跡してきましたが、これは私がこれを行っているためだと思われます。

with open(file1) as fsock1:
    with open(file2, 'a') as fsock2:
        fstring1 = fsock1.read()
        fstring2 = fsock2.read()

read()fsock2からしようとすると、Pythonがスローされます。デバッガーで検査すると、これはファイルが空であると見なすためです。withステートメントではなくデバッグインターパーターでまったく同じコードを実行すると、ファイルが実際にはかなりテキストでいっぱいになっていることがわかるという事実を除いて、これは気になりません...

今のところネスティングwithステートメントはノーノーだと仮定して進めますが、もっと知っている人が違う意見を持っているなら、それを聞いてみたいです。

4

5 に答える 5

44

Pythonのドキュメントで解決策を見つけました。this (Python 3)またはthis (Python 2)を参照してください。

Python 2.7+ を実行している場合は、次のように使用できます。

with open(file1) as fsock1, open(file2, 'a') as fsock2:
    fstring1 = fsock1.read()
    fstring2 = fsock2.read()

これにより、不要なインデントを回避できます。

于 2014-12-18T16:20:45.957 に答える
10

AFAIKでは、追加モードで開いているファイルを読み取ることはできません'a'

于 2010-01-02T02:23:06.393 に答える
8

デバッガーで検査すると、これはファイルが空であると見なすためです。

それは実際には何も読めないからだと思います。可能であっても、ファイルに追加すると、書き込みが発生する準備として、シークポインタがファイルの最後に移動します。

これらのwithステートメントは私にとっては問題なく機能します。

with open(file1) as f:
    with open(file2, 'r') as g:   # Read, not append.
        fstring1 = f.read()
        fstring2 = g.read()

別のポスターが示唆しているように、ここでの使用contextlib.nestedは潜在的に危険に満ちていることに注意してください。これを行うとしましょう:

with contextlib.nested(open(file1, "wt"), open(file2)) as (f_out, f_in):
   ...

ここでのコンテキストマネージャは、一度に1つずつ作成されます。つまり、file2を開くことが失敗した場合(たとえば、file2が存在しないため)、file1を適切にファイナライズできず、ガベージコレクターに任せる必要があります。それは潜在的に非常に悪いことです。

于 2010-01-02T02:32:16.500 に答える
2

withステートメントのネストに問題はありません。むしろ、file2追加のために開いているので、そこから読み取ることはできません。

with何らかの理由でネストステートメントが嫌いな場合は、 contextlib.nested関数を使用してそれを回避できることがよくあります。ただし、壊れたコード(たとえば、追加用にファイルを開いて代わりにそれを読み取ろうとするコード)は機能しません。また、字句的にネストさwithれたステートメントは、他の点では優れているコードを壊しません。

于 2010-01-02T02:28:46.647 に答える
-1

「with」の検索に関しては、単語の前に「+」を付けると、Google がそれを無視するのを防ぐことができます。

于 2010-01-02T02:42:46.603 に答える