我不是专业人士,而且我一直在理解StringIO的用途。我一直在互联网上寻找一些例子。但是,几乎所有的例子都非常抽象。他们只是展示如何使用它。但它们都没有显示“为什么”和“在哪种情况下”应该/将使用它? 提前致谢
P.S。不要与stackoverflow上的这个问题混淆:StringIO Usage比较string和StringIo。
答案 0 :(得分:77)
当你有一些只接受文件的API但你需要使用一个字符串时使用它。例如,使用Python 2中的gzip模块压缩字符串:
import gzip
import StringIO
stringio = StringIO.StringIO()
gzip_file = gzip.GzipFile(fileobj=stringio, mode='w')
gzip_file.write('Hello World')
gzip_file.close()
stringio.getvalue()
答案 1 :(得分:30)
StringIO为您提供类似文件的字符串访问权限,因此您可以使用现有的模块来处理文件,几乎不做任何改动,并使其与字符串一起使用。
例如,假设您有一个记录器将事物写入文件,而您希望通过网络发送日志输出。您可以读取文件并将其内容写入网络,也可以将日志写入StringIO对象并将其发送到其网络目标,而无需触及文件系统。 StringIO可以通过第一种方式轻松实现,然后切换到第二种方式。
答案 2 :(得分:16)
如果你想要一个类似文件的对象,它像文件一样ACTS,但是正在写入内存中的字符串缓冲区:StringIO就是这个工具。如果您正在构建大型字符串(例如纯文本文档)并执行大量字符串连接,您可能会发现使用StringIO而不是一堆mystr += 'more stuff\n'
类型的操作更容易。
答案 3 :(得分:9)
我刚刚在实践中使用了StringIO来做两件事:
print
重定向到sys.stdout
实例以便于分析,对执行大量StringIO
操作的脚本进行单元测试; ElementTree
创建格式良好的XML文档(自定义API请求),然后使用write
通过HTTP连接发送。通常不需要StringIO
,但有时它非常有用。
答案 4 :(得分:8)
我亲自用它做了几件事:
整个文件缓存。我有一个脚本可以读取PDF并对各种事情进行验证。我正在使用的PDF库在其文档构造函数中使用一个打开的文件。我最初只是打开了我感兴趣阅读的PDF,但是当我将其更改为立即将整个文件读入内存然后将StringIO对象传递给PDF库时,我的脚本的运行时间减少了一半。
延迟打印。相同的脚本在读取的每个PDF之前打印一个标题。但是,我可以在命令行上指定是忽略其配置文件中的某些测试,还是仅包含某些测试。如果我忽略给定PDF的所有测试我不希望打印标题,但我不知道在运行测试之前我运行了多少测试(测试可以定义动态地)。因此,我通过将sys.stdout
更改为指向它来将标头捕获到StringIO对象中,每次运行测试时,我都会检查该对象是否包含任何内容。如果是这样,我打印然后将其重置为空。瞧,只有测试的PDF会打印标题。
答案 5 :(得分:0)
Django有一个函数call_command
,用于调用管理命令。此函数将输出打印到stdout,不返回任何值。如果你想知道命令是否成功运行,你必须查看输出并决定。
使用StringIO,您可以捕获输出并检查是否需要输出。
with io.StringIO() as output:
call_command('custom_command', stdout=output)
if 'Success' not in output.getvalue():
print('Custom command failed...')
答案 6 :(得分:0)
我已经用它来代替单元测试的文本文件。
例如,制作一个csv'文件'用pandas进行测试(Python 3):
import io
f = io.StringIO("id,name\n1,brian\n2,amanda\n3,zoey\n")
df = pd.read_csv(f) # pandas takes a file path or a file-like object
来自文档here:
文本I / O的内存中流。调用close()方法时,将丢弃文本缓冲区。
可以通过提供initial_value来设置缓冲区的初始值。
方法getvalue():返回包含缓冲区全部内容的str。
答案 7 :(得分:0)
这是StringIO用例的具体示例:直接向aws s3中写入一些数据,而无需在本地磁盘上创建文件:
import csv
import io
import boto3
data = [
["test", "data", "headers etc", "123","",],
["blah", "123", "35", "blah","",],
["abc", "def", "blah", "yep", "blah"]
]
bucket_name = 'bucket_name_here'
session = boto3.Session(
aws_access_key_id = "fake Access ID"),
aws_secret_access_key = "fake Secret key"),
region_name = "ap-southeast-2")
)
s3 = session.resource('s3')
with io.StringIO() as f:
writer = csv.writer(f, delimiter=",")
writer.writerows(data)
resp = s3.Object(bucket_name, "test.csv").put(Body=f.getvalue())
在S3上享受新的csv,而无需将任何内容写入本地磁盘!