Pythonでは、close()
を呼び出さずにファイルを開くか、try
-_finally
または "with
"ステートメントを使用せずにファイルを閉じると、これが問題になります?または、すべてのファイルを閉じるためにPythonガベージコレクションに依存することは、コーディングの慣行としては十分ですか?たとえば、これを行う場合:
for line in open("filename"):
# ... do stuff ...
...ファイルを閉じることができず、ファイルを閉じることができない例外が発生する可能性があるため、これは問題ですか?または、ファイルがスコープ外になるため、for
ステートメントの終了時に確実に閉じられますか?
この例では、インタープリターが終了する前にファイルが閉じられるとは限りません。現在のバージョンのCPythonでは、CPythonは参照カウントを主要なガベージコレクションメカニズムとして使用しますが、それは言語の機能ではなく実装の詳細であるため、ファイルはforループの終わりで閉じられます。 Pythonの他の実装は、この方法での動作が保証されていません。たとえば、IronPython、PyPy、およびJythonは参照カウントを使用しないため、ループの最後でファイルを閉じません。
コードの移植性が低下するため、CPythonのガベージコレクションの実装に依存するのは悪い習慣です。 CPythonを使用する場合、リソースリークは発生しない可能性がありますが、参照カウントを使用しないPython実装に切り替える場合は、すべてのコードを調べて、すべてのファイルを確認する必要があります。適切に閉じた。
あなたの例では:
with open("filename") as f:
for line in f:
# ... do stuff ...
参照されなくなったファイルを自動的に閉じるPythonもありますが、そうでないものもあり、Pythonインタープリターが終了したときにファイルを閉じるのはO/S次第です。
あなたのためにファイルを閉じるPythonでさえ、タイミングは保証されていません:それは即座であるかもしれませんし、数秒/分/時間/日後であるかもしれません。
そのため、使用しているPythonで問題は発生しないかもしれませんが、ファイルを開いたままにしておくことは絶対に良い習慣ではありません。実際、cpython 3では、システムがファイルを閉じなかった場合、ファイルを閉じる必要があるという警告が表示されます。
道徳:自分の後にクリーンアップ。 :)
この特定のケースでそのような構造を使用することは非常に安全ですが、そのような慣行を一般化するためのいくつかの注意事項があります。
こんにちは同じpythonスクリプトでコンテンツを使用する場合は、ファイル記述子を閉じることが非常に重要です。私は今日、非常に長い時間をかけてデバッグを行っていました。理由は、ファイル記述子を閉じて、変更がファイルに影響を与えた後にのみコンテンツが編集/削除/保存されるからです!
したがって、新しいファイルにコンテンツを書き込み、fdを閉じずに、そのファイル(fdではなく)をそのコンテンツを読み取る別のシェルコマンドで使用している状況があるとします。この状況では、シェルコマンドの内容が期待どおりに取得されず、デバッグしようとしても、バグを簡単に見つけることができません。また、私のブログエントリで詳細を読むことができます http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html
ファイルはガベージコレクションされ、閉じられます。 GCは、ユーザーではなく、いつ閉じられるかを決定します。明らかに、ファイルを使い終わったらすぐにファイルを閉じないと、開いているファイルハンドルの制限に達する可能性があるため、これは推奨される方法ではありません。あなたのfor
ループ内で、さらにファイルを開いて、それらを残しておくとどうなりますか?
I/Oプロセス中、データはバッファリングされます。つまり、データはファイルに書き込まれる前に一時的な場所に保持されます。
Pythonは、書き込みが完了するまで、バッファをフラッシュしません(つまり、ファイルにデータを書き込みます)。これを行う1つの方法は、ファイルを閉じることです。
閉じずにファイルに書き込むと、データはターゲットファイルに到達しません。