我有一个期望文件对象的函数,简化示例:
def process(fd):
print fd.read()
通常称为:
fd = open('myfile', mode='r')
process(fd)
我无法更改此功能,并且我已经在内存中拥有该文件的内容。有没有办法convert
文件内容到文件对象而不将其写入磁盘,所以我可以做这样的事情:
contents = 'The quick brown file'
fd = convert(contents) # ??
process(fd)
答案 0 :(得分:6)
您可以使用StringIO
执行此操作:
这个模块实现了一个类似文件的类StringIO,它读取和 写一个字符串缓冲区(也称为内存文件)。
from StringIO import StringIO
def process(fd):
print fd.read()
contents = 'The quick brown file'
buffer = StringIO()
buffer.write(contents)
buffer.seek(0)
process(buffer) # prints "The quick brown file"
请注意,在Python 3中,它已移至io包中 - 您应使用from io import StringIO
代替from StringIO import StringIO
。
答案 1 :(得分:1)
如果您对“文件状对象”感到满意,则上述答案有效,其中StringIO
类的对象仅是特例。但是,严格意义上来说,StringIO
类的实例不是 '文件对象'(在Python中使用)(即,与内置open
函数返回的对象的类型相同) )。
例如,StringIO
个对象have no fileno
method,故意省略了该方法:
fileno()未实现,因此使用它的代码将触发 尽早例外。
为什么有一个严格的“文件对象”而不只是一个“类似文件的对象”有多个原因。正如the above所说,
使用真实文件通常更快(但不太方便)。
另一个原因是,“文件型”对象(如StringIO
类的对象)不能 用作{{ stdin
中的1}},这是我在Google上发现此问题时想到的用例。这是因为在Python 3.7中,create_subprocess_exec
的第1324行(定义了asyncio.subprocess
使用的subprocess.py
模块),subprocess
方法尝试定义变量{{ 1}},这显然仅在asyncio.subprocess
首先具有_get_handles
方法的情况下有效。因此,真正的“文件对象”和“类似文件的对象”(例如p2cread = stdin.fileno()
类的实例)之间的区别不仅是毫无意义的。
以下内容并不是理想的解决方案,但可以满足我的需求:
stdin
另一方面,它 不能用于您的目的,因为它写入磁盘。而是可以这样:
fileno
两者都可以传递给StringIO
。