关于python:Python3中的StringIO

StringIO in Python3

我使用的是python 3.2.1,无法导入StringIO模块。我用io.StringIO是可以用的,但我不能用在numpygenfromtxt上:

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

我得到以下错误:

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

当我写import StringIO时,上面写着

1
ImportError: No module named 'StringIO'

when i write import StringIO it says there is no such module.

从Python3.0的新功能:

The StringIO and cStringIO modules are gone. Instead, import the io
module and use io.StringIO or io.BytesIO for text and data
respectively.

.

修复某些python 2代码以在python 3中也能工作的一种可能有用的方法(警告:清空):

1
2
3
4
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

Note: This example may be tangential to the main issue of the question and is included only as something to consider when generically addressing the missing StringIO module. For a more direct solution the the message TypeError: Can't convert 'bytes' object to str implicitly, see this answer.


在我的案例中,我使用了:

1
from io import StringIO


在python 3上,numpy.genfromtxt需要字节流。使用以下内容:

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

感谢欧普的提问,罗曼的回答。我必须搜索一下才能找到这个;我希望下面的内容能帮助其他人。

Python 2.7

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np
from StringIO import StringIO

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


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


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


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


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

Python 3.5:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import numpy as np
from io import StringIO
import io

data ="1, abc , 2
 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('
'
)
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('
'
)
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", autostrip=True))
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

旁白:

dtype="sx",其中x=1、2、3,…中的任意一个:

D型。python中s1和s2的区别

"s1和s2字符串是数据类型描述符;第一个表示数组包含长度为1的字符串,第二个是长度为2的字符串。……"


您可以使用六个模块中的stringio:

1
2
3
4
5
6
import six
import numpy

x ="1 3
 4.5 8"

numpy.genfromtxt(six.StringIO(x))

RomanShapovalov的代码应该可以在python 3.x和python 2.6/2.7中使用。下面是完整的示例:

1
2
3
4
5
import io
import numpy
x ="1 3
 4.5 8"

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

输出:

1
2
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,仍然从中产生相同的字节字符串。所以结果是一样的。

由于这是关于StringIO的最流行的问题之一,下面将对import语句和不同的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.BytesIOio.StringIO,这取决于您使用的数据类型。

  • 如果同时支持python 2.6/2.7和3.x,或者试图将代码从2.6/2.7转换为3.x:最简单的选择仍然是使用io.BytesIOio.StringIO。虽然StringIO.StringIO是灵活的,因此似乎更适合2.6/2.7,但这种灵活性可以掩盖3.x中出现的错误。例如,我有一些代码使用StringIO.StringIOio.StringIO,这取决于python版本,但实际上我传递的是一个字节字符串,所以当我开始在python 3.x中测试它时,它失败了,不得不固定的。

    使用io.StringIO的另一个优点是支持通用换行。如果将关键字参数newline=''传递到io.StringIO中,它将能够拆分


    中的任何一行。我发现StringIO.StringIO会在
    上绊倒。

    请注意,如果您从six导入BytesIOStringIO,您将在python 2.x中获得StringIO.StringIO,在python 3.x中获得io的相应类。如果您同意我前面段落的评估,这实际上是一种情况,您应该避免six,而只从io导入。

  • 如果您支持python 2.5或更低版本和3.x:2.5或更低版本需要StringIO.StringIO,那么您也可以使用six。但是要认识到,通常很难同时支持2.5和3.x,所以如果可能的话,您应该考虑将最低支持版本提升到2.6。


为了从这里举例使用python 3.5.2,可以重写如下:

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

更改的原因可能是文件的内容是数据(字节),在以某种方式解码之前,数据(字节)不会生成文本。genfrombytes可能比genfromtxt更好。


试试这个

从Stringio导入Stringio

x="1 3 n 4.5 4.5"

numpy.genfromtxt(字符串(x))