python - StringIO 和与 'with' 语句的兼容性(上下文管理器)

标签 python python-2.x with-statement contextmanager

我有一些带有遗留函数的遗留代码,该函数将文件名作为参数并处理文件内容。代码的工作副本如下。

我想要做的不是为了使用这个遗留函数而将我生成的一些内容写入磁盘,所以我虽然可以使用 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.BytesIOStringIO.StringIO/cStringIO.StringIO 的更强大的替代品。该对象确实支持用作上下文管理器(但仍不能传递给 open())。

关于python - StringIO 和与 'with' 语句的兼容性(上下文管理器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11892623/

相关文章:

python - 导入错误 : No module named 'pandas.indexes'

Python 如何在没有 linter(PyCharm 检查) Unresolved 引用的情况下迭代 StrEnum

python - 将 float 转换为位置格式的字符串(没有科学记数法和错误精度)

基于 Python 标准的动态函数添加到类中

python - pybind11:如何使用上下文管理器实现

c - C 中的 "with"宏

python - 在 Python 中输入对象命名空间

python - django 管理员的自定义 url

python - 使用 Selenium 从网页中提取文本不起作用

python - 使用 while 的等待函数