我有一大堆dict对象。我想将此列表存储在tar文件中以进行远程交换。我已经成功地将json.dumps()字符串写入在' w:gz'中打开的tarfile对象中。模式。
我正在尝试使用管道实现,在' w | gz'中打开tarfile对象。模式。到目前为止,这是我的代码:
from json import dump
from io import StringIO
import tarfile
with StringIO() as out_stream, tarfile.open(filename, 'w|gz', out_stream) as tar_file:
for packet in json_io_format(data):
dump(packet, out_stream)
此代码位于函数' write_data'中。 ' json_io_format'是一个从数据集一次返回一个dict对象的生成器(所以数据包是一个dict)。
这是我的错误:
Traceback (most recent call last):
File "pdml_parser.py", line 35, in write_data
dump(packet, out_stream)
File "/.../anaconda3/lib/python3.5/tarfile.py", line 2397, in __exit__
self.close()
File "/.../anaconda3/lib/python3.5/tarfile.py", line 1733, in close
self.fileobj.close()
File "/.../anaconda3/lib/python3.5/tarfile.py", line 459, in close
self.fileobj.write(self.buf)
TypeError: string argument expected, got 'bytes'
在评论的帮助下进行一些故障排除后,错误是在'与'语句退出,并尝试调用上下文管理器__exit__。我相信这反过来调用TarFile.close()。如果我从'中移除tarfile.open()调用'语句,并故意省略TarFile.close(),我得到这个代码:
with StringIO() as out_stream:
tarfile.open(filename, 'w|gz', out_stream) as tar_file:
for packet in json_io_format(data):
dump(packet, out_stream)
该程序版本完成,但不生成输出文件' filname'并产生此错误:
Exception ignored in: <bound method _Stream.__del__ of <targile._Stream object at 0x7fca7a352b00>>
Traceback (most recent call last):
File "/.../anaconda3/lib/python3.5/tarfile.py", line 411, in __del__
self.close()
File "/.../anaconda3/lib/python3.5/tarfile.py", line 459, in close
self.fileobj.write(self.buf)
TypeError: string argument expected, got 'bytes'
我认为这是由垃圾收集器引起的。有些事情阻止了TarFile对象的关闭。
任何人都可以帮我弄清楚这里发生了什么吗?
答案 0 :(得分:1)
为什么您认为可以将tarfile写入StringIO?这不像你想象的那样有效。
这种方法不会出错,但实际上并不是如何在内存对象的内存中创建tarfile。
from json import dumps
from io import BytesIO
import tarfile
data = [{'foo': 'bar'},
{'cheese': None},
]
filename = 'fnord'
with BytesIO() as out_stream, tarfile.open(filename, 'w|gz', out_stream) as tar_file:
for packet in data:
out_stream.write(dumps(packet).encode())