ファイルのように扱える「仮想ファイルオブジェクト」を使って、テキストやバイナリの操作を試しました。
実ファイルを使わずにデータを操作できるので、テストや一時的な処理に便利でした。
テキストデータを仮想ファイルとして扱う:io.StringIO
io.StringIO
を使うと、文字列をファイルのように扱えます。
たとえばテスト時にダミーのファイルを用意したいときに便利です。
import io
text_data = "これはテスト用の文字列です。\n2行目のテキストです。"
f = io.StringIO(text_data)
# 1行ずつ読み込む
for line in f:
print("読み込み:", line.strip())
読み込み: これはテスト用の文字列です。
読み込み: 2行目のテキストです。
write()
を使って書き込みも可能です。
f = io.StringIO() # 空の仮想ファイルを用意
f.write("Hello, ")
f.write("World!")
print("内容:", f.getvalue()) # getvalue() で全体を取得
内容: Hello, World!
バイナリデータを仮想ファイルとして扱う:io.BytesIO
バイナリデータを扱うときは io.BytesIO
を使います。
画像データや音声データ、バイト列を一時的に扱いたいときに便利です。
import io
binary_data = b'\x00\x01\x02hello\xff'
f = io.BytesIO(binary_data)
# バイナリを読み込んで表示
read = f.read()
print("読み込んだバイト列:", read)
読み込んだバイト列: b'\x00\x01\x02hello\xff'
書き込みも可能です。
f = io.BytesIO()
f.write(b"abc")
f.write(b"123")
print("内容:", f.getvalue())
内容: b'abc123'
メモリ上のファイル専用メソッド(StringIO / BytesIO だけで使える)
io.StringIO
や io.BytesIO
では、通常のファイルオブジェクトにはない専用メソッドがいくつか用意されています。ここではその代表的なものを紹介します。
getvalue()
: 現在の内容をすべて取得
import io
f = io.StringIO()
f.write("テスト中")
print(f.getvalue()) # → 'テスト中'
テスト中
- 現在の全内容を 文字列やバイト列としてコピーして取得します。
- 読み取り位置(カーソル)には影響されません。
getbuffer()
: バッファに直接アクセス(BytesIO専用)
import io
f = io.BytesIO(b"hello")
buf = f.getbuffer()
print(buf[:2]) # → b'he'
buf[0] = ord('H') # 先頭を大文字に変更
print(f.getvalue()) # → b'Hello'
b'he'
b'Hello'
-
getvalue()
はコピーを返すが、getbuffer()
はコピーせずmemoryviewを返します。 - メモリ効率が良く、高速にデータを扱えます。
readinto()
: バイト列を直接バッファに読み込む(BytesIO専用)
import io
f = io.BytesIO(b"ABCDE")
b = bytearray(3)
f.readinto(b)
print(b) # → bytearray(b'ABC')
bytearray(b'ABC')
- 書き込む先のバッファを渡して、その中にデータを直接書き込みます。
- コピーを減らせるので、大量データ処理時に有効です。
【比較まとめ】
メソッド名 | 説明 | 対象 |
---|---|---|
getvalue() |
全内容をコピーして返す | StringIO / BytesIO |
getbuffer() |
コピーせずに中身を参照(memoryview) | BytesIOのみ |
readinto() |
渡したバッファに読み込み(直接書き込み) | BytesIOのみ |
標準入力の模擬:sys.stdin = io.StringIO(...)
Pythonでは通常、input()
を使うとユーザーのキーボード入力を読み取ります。
その入力元は sys.stdin
という「標準入力オブジェクト」です。
この sys.stdin
を io.StringIO()
に差し替えると、キーボードからではなく、指定した文字列から input()
を読み取ることができるようになります。
import io
import sys
sys.stdin = io.StringIO("Hello\nWorld\n")
print(input()) # → Hello
print(input()) # → World
Hello
World
このようにして、テストや自動化の場面でユーザー入力を再現することができます。
標準出力のキャプチャ:sys.stdout = io.StringIO()
通常、print()
した内容は画面(標準出力)に表示されます。
この出力先は sys.stdout
というオブジェクトで管理されています。
sys.stdout
を io.StringIO()
に差し替えると、print()
の内容が画面に出ず、仮想ファイルに書き込まれるようになります。
import sys
import io
sys.stdout = io.StringIO() # 出力先を仮想ファイルに変更
print("テスト") # 画面ではなく、StringIOに書き込まれる
result = sys.stdout.getvalue() # 書き込まれた内容を取得
result に入る値: "テスト\n"
このようにして、print()
の出力内容を文字列としてプログラム内で扱えるようになります。
📌 元に戻す方法
標準出力を変更したままだと、後続の print()
もすべて StringIO
に出力されてしまいます。
以下のように、元に戻すことが推奨されます。
sys.stdout = sys.__stdout__ # 標準出力を元に戻す
print("キャプチャ:", result)
キャプチャ: テスト
おわりに
今回は io.StringIO
と io.BytesIO
を使って、メモリ上でテキストやバイナリをファイルのように扱う方法を学びました。
特に getvalue()
や getbuffer()
のような専用メソッドを使うと、効率的なデータ操作ができることもわかりました。
標準入力・出力の差し替えもテストや自動化で役立ちそうなので、場面に応じて使いこなせるようになりたいです。