IT-Swarm.Net

Python3中的StringIO

我使用的是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'
330
user1591744

当我写入导入StringIO时,它说没有这样的模块。.

来自 Python 3.0中的新功能

StringIOcStringIO模块消失了。而是导入io模块并分别使用io.StringIOio.BytesIO作为文本和数据。.

。.


修复一些Python 2代码的一种可能有用的方法也适用于Python 3(需要注意的话):

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

注意:此示例可能与问题的主要问题相关,并且仅作为一般性地解决缺少的StringIO模块时要考虑的内容。 对于更直接的解决方案,消息TypeError: Can't convert 'bytes' object to str implicitly,请参阅 这个答案 。.

563
nobar

在我的情况下,我使用过:

from io import StringIO
93
Kamesh Jungi

在Python 3上numpy.genfromtxt需要一个字节流。使用以下内容:

numpy.genfromtxt(io.BytesIO(x.encode()))
61
Roman Shapovalov

感谢OP的提问和罗曼的答案。我不得不搜索一下才发现这个;我希望以下帮助其他人。.

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. ...”

22
Victoria Stuart

您可以使用 StringIO 来自 six module:

import six
import numpy

x = "1 3\n 4.5 8"
numpy.genfromtxt(six.StringIO(x))
14
Tiago Coutinho

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并仍然使用相同的字节字符串。所以结果是一样的。.


由于这是关于StringIO的SO最受欢迎的问题之一,这里有一些关于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,它将能够在\n\r\n\r中的任何一行上拆分行。我发现StringIO.StringIO特别会在\r上绊倒。.

    请注意,如果从 BytesIO 导入StringIOsix,则在Python 2.x中获得StringIO.StringIO,在Python 3.x中获得io中的相应类。如果您同意我之前的段落评估,这实际上是一个您应该避免使用six而只是从io导入的情况。.

  • 如果你支持Python 2.5或更低版本和3.x: 你需要StringIO.StringIO为2.5或更低,所以你不妨使用six。但是要意识到通常很难同时支持2.5和3.x,因此如果可能的话,你应该考虑将你支持的最低版本提高到2.6。.

8
S. Kirby

为了从 这里 使用Python 3.5.2创建示例,您可以重写如下:

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

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

6
Pierre ALBARÈDE