はじめに
io.StringIOというものがあります。標準モジュールのioに属します。
io --- ストリームを扱うコアツール — Python 3.7.1 ドキュメント
これがどう便利かというと、「ファイルオブジェクトのように見えるオブジェクト」を作れます。
スポンサーリンク
読み込みに使ってみる
こんな感じですかね。
import io txt = """hoge fuga piyo """ f = io.StringIO(txt) for line in f: print(line, end="") """ => hoge fuga piyo """
何が嬉しいかって? たとえば、これを見てください。
import io import pandas as pd txt = """ number,name,score 1,hoge,100 2,fuga,200 3,piyo,300 """ df = pd.read_csv(io.StringIO(txt), index_col="number") print(df) """ => name score number 1 hoge 100 2 fuga 200 3 piyo 300 """
CSVの文字列を読み込むのに使っています。
pandas.read_csvの第一引数はファイルパスかストリームしか受け付けませんが、io.StringIOをかましてやることでstrを渡せている訳です。
pandas.read_csv — pandas 0.23.4 documentation
「ファイルを作るまでもない、作るのが面倒くさい」ような軽い確認やデバッグ作業に重宝します。
書き込んでみる
io.StringIOが読み込みモードのファイルオブジェクトの代用品として使えることはわかりました。では、書き込みはどうでしょう?
import io f = io.StringIO() f.write("hoge\n") f.close()
このコードはエラーなく終了しますが、特に副作用は得られません。
中身を見たければ、こうします。
import io f = io.StringIO() f.write("hoge\n") print(f.getvalue()) # => hoge f.close()
StringIO.getvalue()はバッファに書き込まれた内容をすべて吐き出します。closeすると呼べなくなるので注意が必要です。
こちらもpandasと組み合わせて使ってみます。
import io import pandas as pd txt = """ number,name,score 1,hoge,100 2,fuga,200 3,piyo,300 """ df = pd.read_csv(io.StringIO(txt), index_col="number") with io.StringIO() as f: f.write(df.to_csv()) print(f.getvalue()) """ => number,name,score 1,hoge,100 2,fuga,200 3,piyo,300 """
使えているようです。
仲間たち
ドキュメントを見るとbytes版のBytesIOもあることがわかる。他にも色々あるようだが、あまり目を通していないのでコメントしない。
まとめ
テキストファイルを相手にするとき、データが小さければソースコードに埋め込めます。そうするとソースコードだけで再現性を確保できて、けっこう良いです。