我有一些带有遗留函数的遗留代码,该函数将文件名作为参数并处理文件内容。代码的工作副本如下。
我想要做的不是为了使用这个遗留函数而将我生成的一些内容写入磁盘,所以我虽然可以使用 StringIO
创建一个对象来代替物理文件名。但是,这不起作用,如下所示。
我认为 StringIO
是解决这个问题的方法。谁能告诉我是否有办法使用这个遗留函数并在参数中传递一些不是磁盘上的文件但可以被遗留函数处理的东西?旧版函数确实有 with
上下文管理器对 filename
参数值进行处理。
我在 google 中遇到的一件事是:http://bugs.python.org/issue1286 ,但这对我没有帮助...
代码
from pprint import pprint
import StringIO
# Legacy Function
def processFile(filename):
with open(filename, 'r') as fh:
return fh.readlines()
# This works
print 'This is the output of FileOnDisk.txt'
pprint(processFile('c:/temp/FileOnDisk.txt'))
print
# This fails
plink_data = StringIO.StringIO('StringIO data.')
print 'This is the error.'
pprint(processFile(plink_data))
输出
这是 FileOnDisk.txt
中的输出:
['This file is on disk.\n']
这是错误:
Traceback (most recent call last):
File "C:\temp\test.py", line 20, in <module>
pprint(processFile(plink_data))
File "C:\temp\test.py", line 6, in processFile
with open(filename, 'r') as fh:
TypeError: coercing to Unicode: need string or buffer, instance found
最佳答案
StringIO
实例是 已经打开的文件。另一方面,open
命令只接受文件名,以返回打开的文件。 StringIO
实例不适合作为文件名。
另外,您不需要关闭 StringIO
实例,因此也不需要将其用作上下文管理器。虽然关闭实例会释放分配的内存,但让垃圾收集器获取对象也是如此。无论如何,contextlib.closing()
context manager如果您想确保在保持对对象的引用的同时释放内存,则可以关闭对象。
如果您的所有遗留代码都可以采用文件名,那么 StringIO
实例就不是可行的方法。使用 tempfile
module而是生成一个临时文件名。
这是一个使用上下文管理器确保临时文件在之后被清理的示例:
import os
import tempfile
from contextlib import contextmanager
@contextmanager
def tempinput(data):
temp = tempfile.NamedTemporaryFile(delete=False)
temp.write(data)
temp.close()
try:
yield temp.name
finally:
os.unlink(temp.name)
with tempinput('Some data.\nSome more data.') as tempfilename:
processFile(tempfilename)
您还可以切换到 io
模块(在 Python 2 和 3 中可用)提供的较新的 Python 3 基础架构,其中 io.BytesIO
是 StringIO.StringIO
/cStringIO.StringIO
的更强大的替代品。该对象确实支持用作上下文管理器(但仍不能传递给 open()
)。
关于python - StringIO 和与 'with' 语句的兼容性(上下文管理器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11892623/