3

我有一个需要文件对象的函数,简化示例:

def process(fd):
    print fd.read()

通常称为:

fd = open('myfile', mode='r')
process(fd)

我无法更改此功能,并且我已经将文件的内容保存在内存中。有没有办法convert将文件内容写入文件对象而不将其写入磁盘,所以我可以这样做:

contents = 'The quick brown file'
fd = convert(contents) # ??
process(fd)
4

2 回答 2

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.

于 2013-08-17T20:30:37.623 回答
1

如果您对“类文件对象”感到满意,则上述答案有效,其中StringIO类的对象只是一种特殊情况。然而,StringIO类的实例并不是Python 中使用的严格意义上的“文件对象”(即与内置open函数返回的内容相同的类型)。

例如,StringIO对象没有fileno方法,故意省略了方法:

fileno() 未实现,因此使用它的代码会提前触发异常。

一个可能是严格的“文件对象”而不仅仅是“类文件对象”的原因有几个。如上所说

使用真实文件通常更快(但不太方便)。

另一个原因是“类文件”对象(如类的对象StringIO不能用作 of 的参数的参数stdin,这是我在 Google 上找到这个问题时想到的用例。这是因为,在 Python 3.7 的第 1324 行(定义使用的模块)中,该方法尝试定义变量,这显然只有在首先具有方法时才有效。因此,真正的“文件对象”和“类文件对象”(如类的实例)之间的区别不仅仅是毫无意义的迂腐。create_subprocess_execasyncio.subprocesssubprocess.pysubprocessasyncio.subprocess_get_handlesp2cread = stdin.fileno()stdinfilenoStringIO

以下不是一个理想的解决方案,但适用于我的目的:

def string_to_file(string):
    file_object = open('temporary_file.temporary', 'w')
    file_object.write(string)
    file_object.flush()
    return file_object

另一方面,它不适用于您的目的,因为它写入磁盘。这可能会起作用:

def string_to_file(string):
    import tempfile
    file_like_object = tempfile.NamedTemporaryFile()
    file_like_object.write(string.encode())
    file_like_object.flush()
    return file_like_object

两者都适用于传递到create_subprocess_exec.

于 2018-07-26T19:55:56.150 回答