- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我已经用谷歌搜索并在 SO 上搜索这些缓冲区模块之间的区别。不过,我还是不是很明白,我觉得我看的一些帖子已经过时了。
在 Python 2.7.11 中,我使用 r = requests.get(url)
下载了特定格式的二进制文件。然后我通过了 StringIO.StringIO(r.content)
、cStringIO.StringIO(r.content)
和 io.BytesIO(r.content)
为解析内容而设计的函数。
所有这三种方法都可用。我的意思是,即使文件是二进制文件,使用 StringIO
仍然是可行的。为什么?
另一件事是关于他们的效率。
In [1]: import StringIO, cStringIO, io
In [2]: from numpy import random
In [3]: x = random.random(1000000)
In [4]: %timeit y = cStringIO.StringIO(x)
1000000 loops, best of 3: 736 ns per loop
In [5]: %timeit y = StringIO.StringIO(x)
1000 loops, best of 3: 283 µs per loop
In [6]: %timeit y = io.BytesIO(x)
1000 loops, best of 3: 1.26 ms per loop
如上图所示,cStringIO > StringIO > BytesIO
。
我发现有人提到 io.BytesIO
总是制作一个新副本,这会花费更多时间。但也有一些帖子提到,这在以后的 Python 版本中已修复。
那么,任何人都可以在最新的 Python 2.x 和 3.x 中对这些 IO
进行彻底的比较吗?
我找到的一些引用资料:
io.StringIO requires a unicode string. io.BytesIO requires a bytes string. StringIO.StringIO allows either unicode or bytes string. cStringIO.StringIO requires a string that is encoded as a bytes string.
但是 cStringIO.StringIO('abc')
不会引发任何错误。
https://review.openstack.org/#/c/286926/1
The StringIO class is the wrong class to use for this, especially considering that subunit v2 is binary and not a string.
http://comments.gmane.org/gmane.comp.python.devel/148717
cStringIO.StringIO(b'data') didn't copy the data while io.BytesIO(b'data') makes a copy (even if the data is not modified later).
2014 年这篇文章中有一个修复补丁。
这是 Eric 示例的 Python 2.7 结果
%timeit cStringIO.StringIO(u_data)
1000000 loops, best of 3: 488 ns per loop
%timeit cStringIO.StringIO(b_data)
1000000 loops, best of 3: 448 ns per loop
%timeit StringIO.StringIO(u_data)
1000000 loops, best of 3: 1.15 µs per loop
%timeit StringIO.StringIO(b_data)
1000000 loops, best of 3: 1.19 µs per loop
%timeit io.StringIO(u_data)
1000 loops, best of 3: 304 µs per loop
# %timeit io.StringIO(b_data)
# error
# %timeit io.BytesIO(u_data)
# error
%timeit io.BytesIO(b_data)
10000 loops, best of 3: 77.5 µs per loop
至于 2.7,cStringIO.StringIO
和 StringIO.StringIO
远比 io
高效。
最佳答案
您应该使用 io.StringIO
处理 unicode
对象和 io.BytesIO
处理 bytes
对象python 2 和 3 都具有向前兼容性(这是 3 所必须提供的)。
这是一个更好的测试(对于 python 2 和 3),它不包括从 numpy 到 str
/bytes
import numpy as np
import string
b_data = np.random.choice(list(string.printable), size=1000000).tobytes()
u_data = b_data.decode('ascii')
u_data = u'\u2603' + u_data[1:] # add a non-ascii character
然后:
import io
%timeit io.StringIO(u_data)
%timeit io.StringIO(b_data)
%timeit io.BytesIO(u_data)
%timeit io.BytesIO(b_data)
在python 2中也可以测试:
import StringIO, cStringIO
%timeit cStringIO.StringIO(u_data)
%timeit cStringIO.StringIO(b_data)
%timeit StringIO.StringIO(u_data)
%timeit StringIO.StringIO(b_data)
其中一些会崩溃,提示非 ascii 字符
Python 3.5 结果:
>>> %timeit io.StringIO(u_data)
100 loops, best of 3: 8.61 ms per loop
>>> %timeit io.StringIO(b_data)
TypeError: initial_value must be str or None, not bytes
>>> %timeit io.BytesIO(u_data)
TypeError: a bytes-like object is required, not 'str'
>>> %timeit io.BytesIO(b_data)
The slowest run took 6.79 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 344 ns per loop
Python 2.7 结果(在不同的机器上运行):
>>> %timeit io.StringIO(u_data)
1000 loops, best of 3: 304 µs per loop
>>> %timeit io.StringIO(b_data)
TypeError: initial_value must be unicode or None, not str
>>> %timeit io.BytesIO(u_data)
TypeError: 'unicode' does not have the buffer interface
>>> %timeit io.BytesIO(b_data)
10000 loops, best of 3: 77.5 µs per loop
>>> %timeit cStringIO.StringIO(u_data)
UnicodeEncodeError: 'ascii' codec cant encode character u'\u2603' in position 0: ordinal not in range(128)
>>> %timeit cStringIO.StringIO(b_data)
1000000 loops, best of 3: 448 ns per loop
>>> %timeit StringIO.StringIO(u_data)
1000000 loops, best of 3: 1.15 µs per loop
>>> %timeit StringIO.StringIO(b_data)
1000000 loops, best of 3: 1.19 µs per loop
关于python - 对 StringIO、StringIO 和 BytesIO 感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37462075/
我在 Python 中从 BytesIO 对象编写 .tar.gz 文件时遇到问题。只编写一个普通的 tarfile 效果很好,但是如果我将写入模式更改为 .tar.gz(或 bz 或 xz),它不会
我使用PyPDF4来合并pdf文件,然后使用合并后的pdf作为HttpResponse。我使用 BytesIO 来获取 PdfFileMerger 的结果。 我使用这段代码让它工作 def merge
当我尝试使用 python "c:\Django\blongo\blongo\blog\manage.py" runserver 我得到: File "C:\Python27\lib\site-pac
我无法理解这两个 BytesIO 对象的区别。如果我这样做: f = open('decoder/logs/testfile.txt', 'rb') file = io.BytesIO(f.read(
我正在尝试在我的程序中使用 Pillow 将相机中的字节串保存到文件中。这是一个示例,其中包含来 self 的相机的一个小原始字节字符串,它应该表示分辨率为 10x5 像素的灰度图像,使用 LSB 和
我有以下代码: 这部分在内存中生成 CSV: def to_csv(events: list) -> io.BytesIO(): if not events: return N
IOBase.truncate 的文档方法说: truncate(size=None) Resize the stream to the given size in bytes (or the cur
尝试在 python3.0 中对字符串进行标记化时,为什么在标记开始之前会出现前导 'utf-8'? 来自python3 docs , tokenize 现在应该按如下方式使用: g = tokeni
我正在开发 Scrapy Spider,尝试使用 slate 从目录中的多个 PDF 文件中提取文本。我对将实际的 PDF 保存到磁盘没有兴趣,因此建议我查看 io.bytesIO 子类 https:
在 OSX 上的 Python 3.5.1 上运行: import io b = io.BytesIO() b.write(b'222') print(b.getvalue()) b.truncate
我想试试 python BytesIO 类。 作为一个实验,我尝试写入内存中的 zip 文件,然后从该 zip 文件中读取字节。因此,我没有将文件对象传递给 gzip,而是传递了一个 BytesIO
我有一个包含 excel 文档数据的 BytesIO 对象。我要使用的库不支持 BytesIO 并且需要一个 File 对象。如何获取我的 BytesIO 对象并将其转换为 File 对象? 最佳答案
我目前正在尝试创建一个用于深度学习的大型数据集,其中包含大量存储在一起的压缩 mp3 文件,因此我没有 10 万个文件必须单独加载。 x = b'' with open("file1.mp3", "r
我想使用 io 中的 BytesIO 类来创建数据流,但是如果我通过它传输大量数据,它会占用大量内存,所以我问是否可以释放“旧”使用的内存“我已经阅读过的数据。 如果 io 模块无法做到这一点,我愿意
查看底部的更新 - 问题略有变化 我正在尝试使用 boto3 的 .download_fileobj 方法将文件从 s3 下载到类似文件的对象,但是当我尝试检查下载的字节流时,它是空的。但是我不确定我
我正在尝试使用 discord.py 发送一个文本文件,但是当我发送该文件时,它似乎是空的。 一个示例片段: bytes = BytesIO() test = b'sadfasdfsa' bytes.
我正在用 python 2.7 制作一个项目,但由于文档是用 python 3.5 编写的,所以它开始在最后部分给我带来一些错误。所以我将所有内容更改为 python 3.5,但由于 bytesIO,
我想直接在模型保存中上传生成的图像,而不必先将其保存到文件中。 型号: avatar = models.ImageField(upload_to="img/", null=True, blank=Tr
有一段不错的、经过测试的 python PyPDF2 代码,一个 .py 设计用于在“真实”操作系统文件上运行。调试完所有内容后,我现在正尝试将其合并到 plPython 函数中,用 io.Bytes
我想将 BytesIO 对象用作连续缓冲区(常见用例)。但是,是否可以从头部删除不再需要的字节? 看起来不像,因为只有一个 truncate() 方法。 ['__class__', '__delatt
我是一名优秀的程序员,十分优秀!