Python3のStringIO


474

Python 3.2.1を使用していStringIOますが、モジュールをインポートできません。私は使用 io.StringIOして動作しますが、次numpygenfromtxtような場合は使用できません。

x="1 3\n 4.5 8"        
numpy.genfromtxt(io.StringIO(x))

次のエラーが発生します。

TypeError: Can't convert 'bytes' object to str implicitly  

そして私がimport StringIOそれを書いたとき

ImportError: No module named 'StringIO'

回答:


774

インポートStringIOを作成すると、そのようなモジュールはないと表示されます。

Python 3.0の新機能から:

StringIOそしてcStringIOモジュールがなくなっています。代わりに、io モジュールをインポートし、テキストio.StringIOまたはio.BytesIOデータにそれぞれまたはを使用します。


一部のPython 2コードを修正してPython 3でも機能するようにするためのおそらく有用な方法(警告エンプター):

try:
    from StringIO import StringIO ## for Python 2
except ImportError:
    from io import StringIO ## for Python 3

注:この例は、質問の主要な問題に接している可能性があり、不足しているStringIOモジュールに一般的に対処するときに考慮すべきものとしてのみ含まれています。 メッセージのより直接的な解決策については、この回答をTypeError: Can't convert 'bytes' object to str implicitly参照してください。


13
これらに言及する価値は同じではないので、TypeErrorこの変更を個別に行うと、s(文字列引数が予期され、 'bytes'を取得した)になる可能性があります。あなたは慎重のpython 3にbtyesとstr(ユニコード)を区別する必要がある
アンディ・ヘイデン

7
私のような初心者の場合:io import StringIOは、io.StringIO()ではなくStringIO()として呼び出すことを意味します。
Noumenon 2015

11
実際にPython 2および3との互換性を保つ方法from io import StringIO
Oleh Prypin

8
これはpython 3のnumpy.genfromtxt()で間違っています。RomanShapovalovの回答を参照してください。
Bill Huang

2
@nobar:後者。元の質問はpython 3.xを使用しており、そこからモジュールStringIOがなくなっているため、from io import BytesIO代わりに適用する必要があります。python 3.5 @ eclipse pyDev + win7 x64で自分でテストしました。私が間違っていた場合は感謝を知らせてください。
Bill Huang


70

Python 3ではnumpy.genfromtxt、バイトストリームが必要です。以下を使用します。

numpy.genfromtxt(io.BytesIO(x.encode()))

24

質問はOPに、回答はRomanに感謝します。これを見つけるには少し検索する必要がありました。以下の情報が他のユーザーの役に立つことを願っています。

Python 2.7

参照:https : //docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html

import numpy as np
from StringIO import StringIO

data = "1, abc , 2\n 3, xxx, 4"

print type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", dtype="|S3", autostrip=True)
"""
[['1' 'abc' '2']
 ['3' 'xxx' '4']]
"""

print '\n', type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

Python 3.5:

import numpy as np
from io import StringIO
import io

data = "1, abc , 2\n 3, xxx, 4"
#print(data)
"""
1, abc , 2
 3, xxx, 4
"""

#print(type(data))
"""
<class 'str'>
"""

#np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
# TypeError: Can't convert 'bytes' object to str implicitly

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", dtype="|S3", autostrip=True))
"""
[[b'1' b'abc' b'2']
 [b'3' b'xxx' b'4']]
"""

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", autostrip=True))
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

余談:

dtype = "| Sx"、ここでx = {1、2、3、...}のいずれか:

dtypes。PythonのS1とS2の違い

「| S1と| S2の文字列はデータ型記述子です。最初の文字列は配列が長さ1の文字列を保持し、2番目は長さ2の文字列を保持することを意味します...」



17

Roman ShapovalovのコードはPython 3.xとPython 2.6 / 2.7で動作するはずです。ここにも完全な例があります:

import io
import numpy
x = "1 3\n 4.5 8"
numpy.genfromtxt(io.BytesIO(x.encode()))

出力:

array([[ 1. ,  3. ],
       [ 4.5,  8. ]])

Python 3.xの説明:

  • numpy.genfromtxt バイトストリーム(Unicodeではなくバイトとして解釈されるファイルのようなオブジェクト)を取ります。
  • io.BytesIOバイト文字列を取り、バイトストリームを返します。io.StringIO一方、はUnicode文字列を受け取り、Unicodeストリームを返します。
  • x Python 3.xではUnicode文字列である文字列リテラルが割り当てられます。
  • encode()Unicode文字列xを取り、それからバイト文字列を作成しio.BytesIO、有効な引数を提供します。

Python 2.6 / 2.7の唯一の違いxは、バイト文字列(from __future__ import unicode_literals使用されていないと想定)でありencode()、バイト文字列xを取り、それでも同じバイト文字列を作成することです。結果は同じです。


これはに関するSOの最も人気のある質問の1つであるためStringIO、インポートステートメントとさまざまなPythonバージョンについてさらに説明します。

文字列を受け取り、ストリームを返すクラスは次のとおりです。

  • io.BytesIO(Python 2.6、2.7、および3.x)-バイト文字列を受け取ります。バイトストリームを返します。
  • io.StringIO(Python 2.6、2.7、および3.x)-Unicode文字列を受け取ります。Unicodeストリームを返します。
  • StringIO.StringIO(Python 2.x)-バイト文字列またはUnicode文字列を受け取ります。バイト文字列の場合、バイトストリームを返します。Unicode文字列の場合、Unicodeストリームを返します。
  • cStringIO.StringIO(Python 2.x)-の高速バージョンですがStringIO.StringIO、非ASCII文字を含むUnicode文字列は使用できません。

StringIO.StringIOとしてインポートされfrom StringIO import StringIO、次にとして使用されることに注意してくださいStringIO(...)。それか、そうしたimport StringIO後で使用しますStringIO.StringIO(...)。モジュール名とクラス名はたまたま同じです。datetimeその方法に似ています。

サポートされているPythonバージョンに応じて、何を使用するか:

  • Python 3.xのみをサポートする場合:使用するデータの種類に応じて、io.BytesIOまたは使用するio.StringIOデータに応じて。

  • Python 2.6 / 2.7と3.xの両方をサポートしている場合、またはコードを2.6 / 2.7から3.xに移行しようとしている場合:最も簡単なオプションは、io.BytesIOまたはを使用することio.StringIOです。StringIO.StringIO柔軟であるため、2.6 / 2.7のために好ましい、その柔軟性が3.xで現れるであろうバグを隠す可能性が思えます たとえば、Pythonのバージョンを使用する、StringIO.StringIOまたはio.StringIOPythonのバージョンに依存するコードがありましたが、実際にはバイト文字列を渡していたため、Python 3.xでのテストに取り掛かると失敗し、修正する必要がありました。

    を使用するもう1つの利点io.StringIOは、ユニバーサル改行のサポートです。キーワード引数を渡す場合newline=''io.StringIO、任意の上に線を分割することができます\n\r\nまたは\r。私はそれが見つかったStringIO.StringIO上でつまずかしまう\r特にインチ

    BytesIOまたはStringIOからインポートsixするとStringIO.StringIO、Python 2.xと適切なクラスioがPython 3.x から取得されることに注意してください。私の前の段落の評価に同意する場合、これは実際には避けてsixio代わりにインポートする必要がある1つのケースです。

  • Python 2.5以下および3.xをサポートしている場合:StringIO.StringIO 2.5以下が必要になるため、を使用することもできますsix。しかし、2.5と3.xの両方をサポートすることは一般に非常に難しいことを理解してください。したがって、可能な限り、サポートされている最低バージョンを2.6に上げることを検討する必要があります。


7

ここの例 をPython 3.5.2で動作させるには、次のように書き換えます。

import io
data =io.BytesIO(b"1, 2, 3\n4, 5, 6") 
import numpy
numpy.genfromtxt(data, delimiter=",")

変更の理由は、ファイルの内容が何らかの方法でデコードされるまでテキストを作成しないデータ(バイト)にあるためです。genfrombytesよりも良い名前かもしれませんgenfromtxt


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.