4

このコードをIPython3シェルで使用する場合

 >>>data = open('file').read()

次に、開いているファイル記述子を確認します。

 lsof | grep file

空のリストが見つかりました

そして私がこれを使うとき:

>>>open('file')

lsofは2つのアイテムを示しています。問題は、最初の操作がfdを閉じるのに、2番目の操作が閉じないのはなぜですか?ガベージコレクターは、参照なしでファイルオブジェクトを削除する必要があると思いました。

値を再割り当てするときに、インタプリタの「_」変数について知っています

>>>111
>>>_
111

ただし、記述子は開いたままです。繰り返すとき

>>>open('file')

n回2*n個の開かれた記述子があります

4

3 に答える 3

4

2 番目の例では、ファイル ハンドルは対話型インタープリター変数によって保持されます_。これにより、最後に評価された式にアクセスできます。などの別の式を評価すると、ファイルが によって開かれている1+1と報告されなくなっていることに注意してください。lsof

Mike Byers が指摘したように、この動作は CPython に固有のものであり、さらにファイル オブジェクトがどのように使用されるかという正確な状況に固有のものです。コードの実行方法に関係なく、ファイルが確実に閉じられるようにするには、次のwithステートメントを使用します。

with open('file') as fp:
    data = fp.read()
于 2012-11-09T20:39:26.890 に答える
2

デフォルトのPython実装は、ガベージコレクションと参照カウントの両方を使用します。最初の例では、ファイルオブジェクトの参照カウントがゼロに低下するため、ガベージコレクターが実行される前でもすぐに閉じられます。

2番目のバージョンはこれと同等です:

_ = open('file')

ファイルはまだ参照され_ているため、別のコマンドを実行するまでファイルは有効です。

この動作はCPythonに固有であることに注意してください。IronPythonなどの他の実装では、ファイルを閉じるのにそれほど速くない場合があるため、ファイルを使い終わったら、実際にファイルを閉じる必要があります。これを行う良い方法は、withステートメントを使用することです。

with open('file') as f:
    data = f.read()

関連している

于 2012-11-09T20:32:59.933 に答える
2

これは、使用している対話型インタープリターが、最後に返されたオブジェクトへの暗黙的な参照を保持しているためです。その参照の名前は_.

Python2> open("/etc/hosts") 
<open file '/etc/hosts', mode 'r' at 0xf2c390> 
Python2> _ 
<open file '/etc/hosts', mode 'r' at 0xf2c390>

ですから、あなたがそれを見るとき、それはまだ「生きている」のです。他のことをします:

Python2> max(0,1)
1

ファイルは参照されなくなったため、閉じられます。

しかし、これは、本当に閉じたいファイルを明示的に閉じる必要がある理由の良い例です。

于 2012-11-09T20:40:59.950 に答える