中学理科1626207 views
高校化学2913383 views
MathPython491378 views
高校倫理1433119 views
世界の国560595 views
英語607877 views
高校国語785655 views
高校日本史189857 views
高校物理158224 views
LaTeX957300 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 文を使えばこの問題は発生しない。