私はdictオブジェクトの大きなリストを持っています。このリストをtarファイルに保存して、リモートで交換したいと思います。私は、 'w:gz'モードで開いたtarfileオブジェクトにjson.dumps()文字列を書き込むことで成功しました。JSONを直接tarファイルにダンプする
「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'は、データセットから一度に1つの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'ブロックの最後(ループの最後の後)にあります。 'tarfile'コンテキストマネージャーへの' __close__'呼び出しは、私が完全に理解していない何らかの方法でデータに問題があります(これは答えではなくコメントです)。デバッグを簡単にするために、ループなしで1つの値を単にダンプするだけでテストできます。 – Blckknght
tarfile宣言をwith文から削除する関数を書き直して、同じエラーが発生しました。 tar_file.close()を削除しました。ガベージコレクタがストリームオブジェクトを削除しようとすると、エラーが発生します。そう、はい、tarfileを閉じることに何か問題があります。私はこれを反映するために、私の質問を修正します、チップのおかげで。 – kingledion