У меня есть большой список объектов dict. Я хотел бы сохранить этот список в tar-файле для обмена удаленно. Я сделал это успешно, написав строку json.dumps() для объекта tarfile, открытого в режиме «w: gz».Сбрасывание JSON непосредственно в tarfile
Я пытаюсь выполнить реализацию по каналам, открыв объект tarfile в режиме «w | gz». Вот мой код:
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__. I BELIEVE что это в свою очередь вызывает 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.
Может ли кто-нибудь помочь мне разобраться, что здесь происходит?
Ваше исключение не происходит во время цикла, а скорее в конце блока 'with' (который находится после окончания цикла). В вызове '__close__' менеджера контекста tarfile возникают проблемы с данными, которые я не совсем понимаю (таким образом, это комментарий, а не ответ). Чтобы упростить отладку, вы могли бы протестировать, просто используя 'dump'ing одно значение без цикла. – Blckknght
Я переписал функцию, чтобы удалить объявление tarfile из инструкции with и получил ту же ошибку. Я удалил tar_file.close(), и теперь я получаю ошибку, когда сборщик мусора пытается удалить объект потока. Так что да, что-то не так с закрытием tarfile. Я поправлю свой вопрос, чтобы отразить это, спасибо за подсказку. – kingledion