python - 使 Python 内置流包装器不关闭底层 BytesIO
问题描述
我正在创建内存文件作为io.BytesIO
对象。
文件内容是使用顶部的各种内置 Python 包装器创建的,例如io.TextIOWrapper
or csv.DictWriter
(只是一个示例,我正在使用更多 Python 的 stdlib):
def generate_file():
raw_bytes = io.BytesIO()
with io.TextIOWrapper(raw_bytes, encoding='utf-8') as wrapper:
writer = csv.DictWriter(wrapper, ["a", "b", "c"])
writer.writeheader()
return raw_bytes
这种方法失败了,因为TextIOWrapper
将关闭其底层流 = our raw_bytes
:
generate_file().seek(0)
ValueError: I/O operation on closed file.
根据https://bugs.python.org/issue21363,可以分离缓冲区,但这也无济于事,因为上下文管理器会引发另一个错误:
def generate_file():
raw_bytes = io.BytesIO()
with io.TextIOWrapper(raw_bytes, encoding='utf-8') as wrapper:
writer = csv.DictWriter(wrapper, ["a", "b", "c"])
writer.writeheader()
wrapper.detach()
return raw_bytes
generate_file().seek(0)
ValueError: underlying buffer has been detached
我找到了两个解决方案:
部分破解:不要使用上下文管理器,然后上面的方法有效(上下文管理器不会尝试访问分离的对象)。
一般技巧:让 BytesIO 忽略任何
close()
调用:
class NonClosingBytesIO(io.BytesIO):
def close(self):
pass
def generate_file():
raw_bytes = NonClosingBytesIO()
with io.TextIOWrapper(raw_bytes, encoding='utf-8') as wrapper:
writer = csv.DictWriter(wrapper, ["a", "b", "c"])
writer.writeheader()
return raw_bytes
generate_file().getvalue()
b'a,b,c\r\n'
问:这样安全吗?你能想出一个更好(更清洁)的解决方案吗?
解决方案
推荐阅读
- regex - 解析 git 历史记录并对其进行模式匹配,一旦找到匹配项,就在变量中捕获附近的值
- ssis - SSIS 2005 至 2019
- mips - how to change value at register in MIPS
- java - 为什么在类型转换器的帮助下尝试在 Room 数据库中保存列表时出现错误?
- python - 如何训练用于无人机姿态估计的自定义关键点检测器。探测器2
- javascript - 如何使用 vba 从网页中的表值中正确提取内部文本?
- c# - 如何使用 C# 从 PDF 或 XPS 中提取具有格式的文本?
- r - 在 R 中将平面文件保存为 SQL 数据库,而不将其 100% 加载到 RAM 中
- javascript - JavaScript 减少函数代码混乱?
- python - 自引用中的sqlalchemy column_property