中学理科1627103 views
高校国語786032 views
高校化学2914696 views
高校倫理1434311 views
英語608813 views
雑学1472779 views
いろは2990790 views
高校物理158476 views
りんご195442 views
高校生物550095 views
Help
Tools

English

ファイルを開いたまま閉じ忘れる問題と with 文の重要性

ファイルを開いた後に close() を呼び忘れると、リソースリークやデータ損失を引き起こす可能性がある。

close() を忘れるとどうなるか

# ❌ アンチパターン
f = open('data.txt', 'w')
f.write('some data')
# close() を忘れている

この場合、以下の問題が発生する可能性がある。

書き込んだデータがディスクに反映されない(バッファに残ったまま)
ファイルディスクリプタが枯渇する
他のプロセスがファイルにアクセスできない(Windows で顕著)
プログラムが異常終了するとデータが消える

例外が発生すると close() されない

close() を書いていても、その前に例外が発生すると呼ばれない。

# ❌ 例外が発生すると close() されない
f = open('data.txt', 'w')
process_data(f)  # ここで例外が発生すると…
f.close()  # この行は実行されない

try-finally で対処できるが、冗長になる。

# △ 動くが冗長
f = open('data.txt', 'w')
try:
    process_data(f)
finally:
    f.close()

with 文を使う

with 文を使えば、ブロックを抜けるときに自動的にファイルが閉じられる。例外が発生しても確実に閉じられる。

# ✅ 正しい方法
with open('data.txt', 'w') as f:
    f.write('some data')
# ここで自動的に close() される

例外が発生した場合も安全だ。

with open('data.txt', 'w') as f:
    process_data(f)  # 例外が発生しても
# 確実に close() される

複数ファイルを開く

複数のファイルを同時に開く場合も with 文を使う。

# ✅ 複数ファイルを同時に開く
with open('input.txt', 'r') as fin, open('output.txt', 'w') as fout:
    for line in fin:
        fout.write(line.upper())

Python 3.10 以降では、括弧で囲んで複数行に分けられる。

with (
    open('input.txt', 'r') as fin,
    open('output.txt', 'w') as fout,
    open('log.txt', 'a') as flog
):
    # 処理
    pass

pathlib でも with を使う

pathlibopen() メソッドでも同様に with 文を使うべきだ。

from pathlib import Path

path = Path('data.txt')

with path.open('w') as f:
    f.write('some data')

ただし、単純な読み書きなら read_text()write_text() がさらに簡潔だ。

from pathlib import Path

path = Path('data.txt')

# 読み込み
content = path.read_text()

# 書き込み
path.write_text('some data')

これらのメソッドは内部で適切にファイルを閉じるため、with 文を書く必要がない。

ファイルディスクリプタの枯渇

close() し忘れたファイルが蓄積すると、OS のファイルディスクリプタ上限に達してエラーになる。

# ❌ ファイルディスクリプタが枯渇する例
files = []
for i in range(10000):
    f = open(f'file_{i}.txt', 'w')
    files.append(f)  # close() されないファイルが蓄積
# OSError: [Errno 24] Too many open files

with 文を使えばこの問題は発生しない。