今回は io.StringIO
のストリームを close()
した後に、メソッドを呼び出すとどうなるのかを学習しました。
ファイルと似たような使い方ができる StringIO
ですが、「閉じたあとも操作できるのか?」という点が気になったので、実際に試してみた記録です。
StringIOとは?
io.StringIO
は、文字列を「ファイルのように」扱えるオブジェクトです。
通常のファイルと同じように write()
や read()
、getvalue()
などのメソッドを使って操作できます。
import io
stream = io.StringIO()
stream.write("Hello, world!")
print(stream.getvalue())
Hello, world!
close()した後に操作すると?
StringIO
オブジェクトも、普通のファイルと同様に close()
メソッドで閉じることができます。
問題は、その後に操作しようとするとどうなるか?です。
実験コード
import io
stream = io.StringIO("Hello!")
stream.close()
# 閉じたあとにメソッドを使おうとする
print(stream.getvalue())
ValueError: I/O operation on closed file.
解説
-
close()
を呼ぶと、そのStringIO
オブジェクトは 使用不可の状態 になります。 - その状態で
getvalue()
やread()
、write()
を呼ぶとValueError
が発生します。 - エラーメッセージは次のようになります:
ValueError: I/O operation on closed file.
with文では自動でclose()される
StringIO
を with
文で使うと、ブロックを抜けたタイミングで自動的に close()
が呼ばれます。
これは便利ですが、ブロックの外では操作できなくなることに注意が必要です。
実験コード
import io
with io.StringIO("hello") as s:
print(s.read())
# withブロックを抜けたあとにgetvalue()を呼ぶ
print(s.getvalue())
hello
ValueError: I/O operation on closed file.
ポイント
-
with
文の中ではストリームが開いているので、自由に操作できます。 - しかし、ブロックを抜けた瞬間に自動で close() されるため、外で操作しようとするとやはり
ValueError
が発生します。
✅ まとめ
-
io.StringIO
は文字列を「ファイルのように」操作できる便利なクラス -
close()
を呼ぶと、そのオブジェクトは使えなくなる - 閉じたオブジェクトで
read()
やgetvalue()
を呼ぶとValueError: I/O operation on closed file.
が発生する -
with
文を使うと自動で close() されるが、ブロック外での操作はやはりエラーになる
今回は、StringIO
を閉じたあとの挙動について確認した内容をまとめました。