Python 何时使用 StringIO,而不是加入字符串列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4733693/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 17:15:18  来源:igfitidea点击:

When is StringIO used, as opposed to joining a list of strings?

pythonstringio

提问by simha

Using StringIO as string buffer is slower than using list as buffer.

使用 StringIO 作为字符串缓冲区比使用列表作为缓冲区慢。

When is StringIO used?

什么时候使用 StringIO?

from io import StringIO


def meth1(string):
    a = []
    for i in range(100):
        a.append(string)
    return ''.join(a)

def meth2(string):
    a = StringIO()
    for i in range(100):
        a.write(string)
    return a.getvalue()


if __name__ == '__main__':
    from timeit import Timer
    string = "This is test string"
    print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
    print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())

Results:

结果:

16.7872819901
18.7160351276

采纳答案by plundra

If you measure for speed, you should use cStringIO.

如果您测量速度,则应使用cStringIO.

From the docs:

文档

The module cStringIO provides an interface similar to that of the StringIO module. Heavy use of StringIO.StringIO objects can be made more efficient by using the function StringIO() from this module instead.

模块 cStringIO 提供了一个类似于 StringIO 模块的接口。通过使用此模块中的函数 StringIO() 可以更高效地使用 StringIO.StringIO 对象。

But the point of StringIO is to be a file-like object, for when something expects such and you don't want to use actual files.

但是 StringIO 的重点是成为一个类似文件的对象,因为当某些事情需要这样并且您不想使用实际文件时。

Edit:I noticed you use from io import StringIO, so you are probably on Python >= 3 or at least 2.6. The separate StringIO and cStringIO are gone in Py3. Not sure what implementation they used to provide the io.StringIO. There is io.BytesIOtoo.

编辑:我注意到您使用了from io import StringIO,所以您可能使用的是 Python >= 3 或至少 2.6。单独的 StringIO 和 cStringIO 在 Py3 中消失了。不确定他们使用什么实现来提供 io.StringIO。也有io.BytesIO

回答by TryPyPy

The main advantage of StringIO is that it can be used where a file was expected. So you can do for example (for Python 2):

StringIO 的主要优点是它可以用于需要文件的地方。所以你可以做例如(对于Python 2):

import sys
import StringIO

out = StringIO.StringIO()
sys.stdout = out
print "hi, I'm going out"
sys.stdout = sys.__stdout__
print out.getvalue()

回答by Lennart Regebro

Well, I don't know if I would like to call that using it as a "buffer", you are just multiplying a string a 100 times, in two complicated ways. Here is an uncomplicated way:

好吧,我不知道我是否想将其称为“缓冲区”,您只是以两种复杂的方式将字符串乘以 100 次。这是一个简单的方法:

def meth3(string):
    return string * 100

If we add that to your test:

如果我们将其添加到您的测试中:

if __name__ == '__main__':

    from timeit import Timer
    string = "This is test string"
    # Make sure it all does the same:
    assert(meth1(string) == meth3(string))
    assert(meth2(string) == meth3(string))
    print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
    print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())
    print(Timer("meth3(string)", "from __main__ import meth3, string").timeit())

It turns out to be way faster as a bonus:

事实证明,作为奖励要快得多:

21.0300650597
22.4869811535
0.811429977417

If you want to create a bunch of strings, and then join them, meth1() is the correct way. There is no point in writing it to StringIO, which is something completely different, namely a string with a file-like stream interface.

如果你想创建一堆字符串,然后将它们连接起来, meth1() 是正确的方法。将其写入 StringIO 是没有意义的,这是完全不同的东西,即具有类似文件的流接口的字符串。

回答by Jagadeesh Sali

Another approach based on Lennart Regebro approach. This is faster than list method (meth1)

另一种基于 Lennart Regebro 方法的方法。这比列表方法(meth1)快

def meth4(string):
    a = StringIO(string * 100)
    contents = a.getvalue()
    a.close()
    return contents

if __name__ == '__main__':
    from timeit import Timer
    string = "This is test string"
    print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
    print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())
    print(Timer("meth3(string)", "from __main__ import meth3, string").timeit())
    print(Timer("meth4(string)", "from __main__ import meth4, string").timeit())

Results (sec.):

结果(秒):

meth1 = 7.731315963647944

meth2 = 9.609279402186985

meth3 = 0.26534052061106195

meth4 = 2.915035489152274

meth1 = 7.731315963647944

meth2 = 9.609279402186985

meth3 = 0.26534052061106195

meth4 = 2.915035489152274