使用 numpy 的 StringIO 模块 python 中的错误
Bug in StringIO module python using numpy
非常简单的代码:
import StringIO
import numpy as np
c = StringIO.StringIO()
c.write("1 0")
a = np.loadtxt(c)
print a
我得到一个空数组 + 警告说 c 是一个空文件。
我通过添加解决了这个问题:
d=StringIO.StringIO(c.getvalue())
a = np.loadtxt(d)
我觉得这样的事情不应该发生,这是怎么回事?
因为文件对象的'position'写入后在文件末尾。所以numpy读取的时候,是从文件末尾读到末尾,这没什么。
查找到文件的开头,然后就可以了:
>>> from StringIO import StringIO
>>> s = StringIO()
>>> s.write("1 2")
>>> s.read()
''
>>> s.seek(0)
>>> s.read()
'1 2'
StringIO
是一个类似文件的对象。因此它具有与文件一致的行为。有一个文件指针的概念——文件中的当前位置。当您将数据写入 StringIO
对象时,文件指针会调整到数据的末尾。当你试图读取它时,文件指针已经在缓冲区的末尾,所以没有数据返回。
要回读它,您可以执行以下两项操作之一:
- 使用您已经发现的
StringIO.getvalue()
。这个returns
从缓冲区开始的数据,保持文件指针不变。
- 使用
StringIO.seek(0)
将文件指针重新定位到
缓冲区,然后调用 StringIO.read()
读取数据。
演示
>>> from StringIO import StringIO
>>> s = StringIO()
>>> s.write('hi there')
>>> s.read()
''
>>> s.tell() # shows the current position of the file pointer
8
>>> s.getvalue()
'hi there'
>>> s.tell()
8
>>> s.read()
''
>>> s.seek(0)
>>> s.tell()
0
>>> s.read()
'hi there'
>>> s.tell()
8
>>> s.read()
''
有一个例外。如果您在创建 StringIO
时提供一个值,缓冲区将使用该值初始化,但文件指针将定位在缓冲区的开头:
>>> s = StringIO('hi there')
>>> s.tell()
0
>>> s.read()
'hi there'
>>> s.read()
''
>>> s.tell()
8
这就是为什么它在您使用
时有效
d=StringIO.StringIO(c.getvalue())
因为您在创建时初始化 StringIO
对象,并且文件指针位于缓冲区的开头。
非常简单的代码:
import StringIO
import numpy as np
c = StringIO.StringIO()
c.write("1 0")
a = np.loadtxt(c)
print a
我得到一个空数组 + 警告说 c 是一个空文件。
我通过添加解决了这个问题:
d=StringIO.StringIO(c.getvalue())
a = np.loadtxt(d)
我觉得这样的事情不应该发生,这是怎么回事?
因为文件对象的'position'写入后在文件末尾。所以numpy读取的时候,是从文件末尾读到末尾,这没什么。
查找到文件的开头,然后就可以了:
>>> from StringIO import StringIO
>>> s = StringIO()
>>> s.write("1 2")
>>> s.read()
''
>>> s.seek(0)
>>> s.read()
'1 2'
StringIO
是一个类似文件的对象。因此它具有与文件一致的行为。有一个文件指针的概念——文件中的当前位置。当您将数据写入 StringIO
对象时,文件指针会调整到数据的末尾。当你试图读取它时,文件指针已经在缓冲区的末尾,所以没有数据返回。
要回读它,您可以执行以下两项操作之一:
- 使用您已经发现的
StringIO.getvalue()
。这个returns 从缓冲区开始的数据,保持文件指针不变。 - 使用
StringIO.seek(0)
将文件指针重新定位到 缓冲区,然后调用StringIO.read()
读取数据。
演示
>>> from StringIO import StringIO
>>> s = StringIO()
>>> s.write('hi there')
>>> s.read()
''
>>> s.tell() # shows the current position of the file pointer
8
>>> s.getvalue()
'hi there'
>>> s.tell()
8
>>> s.read()
''
>>> s.seek(0)
>>> s.tell()
0
>>> s.read()
'hi there'
>>> s.tell()
8
>>> s.read()
''
有一个例外。如果您在创建 StringIO
时提供一个值,缓冲区将使用该值初始化,但文件指针将定位在缓冲区的开头:
>>> s = StringIO('hi there')
>>> s.tell()
0
>>> s.read()
'hi there'
>>> s.read()
''
>>> s.tell()
8
这就是为什么它在您使用
时有效d=StringIO.StringIO(c.getvalue())
因为您在创建时初始化 StringIO
对象,并且文件指针位于缓冲区的开头。