日々drdrする人のメモ

今日も明日もdrdr

Python2/3におけるストリームを扱うモジュールの違い

Python2,3で共存するコードを書いてて、ストリームを扱ったらPython2/3でモジュールの違いがあって混乱したので整理。

ストリームを扱えるモジュール

Python2では、標準でStringIOモジュールが提供されている。他にcStringIOモジュールもあり、使えるのであればこっちで処理した方が高速で処理できる。
また、Python2,3両方でioモジュールが提供されており、Python3ではStringIOモジュールが廃止されてioモジュールが標準になった感じらしい。

StringIO.StringIO (cStringIO.StringIO)

7.5. StringIO — ファイルのように文字列を読み書きする — Python 2.7.13 ドキュメント
リファレンスによると、unicodeもstrも両方受け付けるらしい。
(ただし、混同した時に8ビット文字列でUnicodeError返す可能性があるらしい)

io.StringIO, io.BytesIO in Python2

15.2. io — ストリームを扱うコアツール — Python 2.7.13 ドキュメント
冒頭のNoteより引用

注釈: このモジュールはもともと、Python 3.x のために設計されたものなので、このドキュメントの中で使われるすべての “bytes” は (bytes がエイリアスとなる) str 型のことで、すべての “text” は unicode 型のことです。さらに、 io API では、この 2 つの型は入れ替えられません。

これより、Text I/Oであるio.StringIOはunicode用であり、BytesIOはbytesと型として同じであるstr用であることがわかる。

io.StringIO, io.BytesIO in Python3

16.2. io — ストリームを扱うコアツール — Python 3.6.1 ドキュメント
リファレンスによると、テキストI/OであるStringIOはstrオブジェクト、バイナリI/OであるBytesIOはbytes-likeオブジェクトを受け取ると書いてある。

まとめ

どのモジュールがどの型に対応しているのかをまとめたのがこちら。

(c)StringIO.StringIO io.StringIO io.BytesIO
str,bytes (Python2) ×
unicode (Python2) ×
str (Python3) - ×
bytes-like (Python3) - ×

str型を扱えるストリームを両方ioストリームから利用しようと思ったら、Python2,3で逆になっているのでややこしい。