我收到的数据是 bytes
因此我需要 类似文件的 临时容器。据我所知 BytesIO
是 类文件 对象,但是 json.load()
不起作用:
In [1]: import json
...: from io import BytesIO, TextIOWrapper
In [2]: d, b = dict(a=1, b=2), BytesIO()
In [3]: b.write(json.dumps(d).encode())
Out[3]: 16
In [4]: b.seek(0)
Out[4]: 0
In [5]: b.read()
Out[5]: b'{"a": 1, "b": 2}'
In [6]: b.seek(0)
Out[6]: 0
In [7]: json.load(b)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-233ac51d2711> in <module>()
----> 1 json.load(b)
/usr/lib/python3.5/json/__init__.py in load(fp, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
266 cls=cls, object_hook=object_hook,
267 parse_float=parse_float, parse_int=parse_int,
--> 268 parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
269
270
/usr/lib/python3.5/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
310 if not isinstance(s, str):
311 raise TypeError('the JSON object must be str, not {!r}'.format(
--> 312 s.__class__.__name__))
313 if s.startswith(u'\ufeff'):
314 raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
TypeError: the JSON object must be str, not 'bytes'
一种有效的方法:
In [8]: json.loads(b.getvalue().decode())
Out[8]: {'a': 1, 'b': 2}
另一个,大概更有效率?
In [10]: b.seek(0)
Out[10]: 0
In [11]: json.load(TextIOWrapper(b, encoding='utf-8'))
Out[11]: {'a': 1, 'b': 2}
我有更多(更好)的选择吗?如果否,应首选上述方法中的哪一种?
原文由 NarūnasK 发布,翻译遵循 CC BY-SA 4.0 许可协议
我建议使用
TextIOWrapper
有两个原因:fileobj.read().decode()
会不必要地将所有 10MB 加载到内存中,但是如果你使用TextIOWrapper
那么在JsonDecodeError
之前只会加载几个字节---
被抛出。