質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

3回答

1253閲覧

python で open 関数を使った時に close をする必要があるのかないのか

goro_gnm

総合スコア42

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/28 08:00

open 関数は次の2種類の使い方があると聞きました。

### way 1 ### f = open(file_path) print(type(f)) # <class '_io.TextIOWrapper'> f.close() ### way 2 ### with open(file_path) as f: print(type(f)) # <class '_io.TextIOWrapper'>

前者の場合、用が済んだら開いたファイルオブジェクトを close() でクローズする必要があるが、後者のように with ブロックを使えばブロックの終了時に自動的にクローズされるため、閉じ忘れがなくて便利と聞きました。

ここまでは理解できました。

気になっているのは次の場合です。
with ブロックを使わない方法として、ファイルオブジェクトを他の変数に入れないで read 関数をそのまま使ってしまう方法もあると思うのですが、

file_content = open(file_path).read()

この場合 close 関数は不必要という認識であっていますでしょうか。

またこの答えを得るために見るべきドキュメントなどあれば、指南していただけるとうれしいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

https://docs.python.org/ja/3/reference/datamodel.html

オブジェクトには、開かれたファイルやウィンドウといった、 "外部 (external) の" リソースへの参照を含むものがあります。これらのリソースは、オブジェクトがごみ収集された際に解放されるものと理解されていますが、ごみ収集が行われる保証はないので、こうしたオブジェクトは外部リソースを明示的に解放する方法、大抵は close() メソッドも提供しています。こうしたオブジェクトは明示的に close するよう強く奨めます。

ガベージコレクションの対象になった時に、クローズされるであろうと期待されますが保証はありません
"明示的に close するよう強く奨めます" とある通りかと思います。


他の関連しそうな記述

https://docs.python.org/ja/3/glossary.html#term-interpreter-shutdown

このフェーズは ガベージコレクタ を複数回呼び出します。 これによりユーザー定義のデストラクターや weakref コールバックが呼び出されることがあります。 シャットダウンフェーズ中に実行されるコードは、それが依存するリソースがすでに機能しない(よくある例はライブラリーモジュールや warning 機構です) ために様々な例外に直面します。

https://docs.python.org/ja/3/reference/datamodel.html#object.del

インタプリタが終了したときに、残存しているオブジェクトの __del__() メソッドが呼び出される保証はありません。


file_content = open(file_path).read()

の場合、文の実行直後に、オープンしたファイルオブジェクトは参照カウントが0になってガベージコレクションの対象になります。
この文自体が正常に実行されたなら、ほぼ問題なくいつかクローズされると期待されます。
(が、インタプリタが異常終了したりすれば"保証はない"ことに変わりはありません)

投稿2021/12/28 08:49

編集2021/12/28 09:03
quickquip

総合スコア11235

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

goro_gnm

2021/12/28 17:27

ドキュメントも提示してくださりありがとうございます。大変参考になりました。 クローズが推奨されるとのことですが、 file_content = open(file_path).read() と書いた場合クローズすることってできないという認識であっていますか? 結論としては、この書き方では明示的なクローズができないので、最初に示した2つの方法で書くのが望ましいということですかね。
quickquip

2021/12/28 23:51 編集

> この書き方では明示的なクローズができない それでいいと思います。 > 最初に示した2つの方法で書くのが望ましい 上の文よりは f = open(file_path) try: □print(type(f)) finally: □f.close() が望ましく、それよりはwith文で書くのがいい、という感覚です。 書き捨ての生存期間が**短い**コードであれば、上の方でも**現実には**問題になることはないと思います。
goro_gnm

2022/01/01 15:21

わかりました、ありがとうございます。 ちなみに生存期間が長いコードというのは、実際にあるものですか?よかったら具体例など教えていただけるとうれしいです。
guest

0

open(file_path).read()

だと、オープンされたファイルはクローズされていないので、クローズが必要です。

同時にオープンできるファイルの最大数があるので、たとえば、多くのLinuxでは数千のファイルをクローズせずにオープンは出来ませんので、
open(file_path).read()を1024個以上並べるとエラーになります。
そこまでの数をオープンしないのであれば、どういう書き方であれ、明示的にクローズしなくても大丈夫です。

投稿2021/12/28 14:25

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

  • この場合 close 関数は不必要という認識であっていますでしょうか。

どういうプログラムなのかによります。

file_content = open(file_path).read()のあとに簡単な処理をして終了してしまうのであれば問題はありません。
開いた後に長い時間閉じなければ問題になるでしょう。

ループの中でfile_content = open(file_path).read()を回しているようなコードであれば大きな問題になります。それはOSのopenがカーネル部分で使用するリソースを占有し続けるからです。

投稿2021/12/28 11:02

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問