json --- JSON 編碼器與解碼器¶
JSON (JavaScript Object Notation) 是一個輕量化的資料交換格式,在 RFC 7159(其廢棄了 RFC 4627)及 ECMA-404 裡面有詳細說明,它啟發自 JavaScript 的物件字面語法 (object literal syntax)(雖然它並不是 JavaScript 的嚴格子集 [1])。
備註
The term "object" in the context of JSON processing in Python can be ambiguous. All values in Python are objects. In JSON, an object refers to any data wrapped in curly braces, similar to a Python dictionary.
警告
當剖析無法信任來源的 JSON 資料時要小心。一段惡意的 JSON 字串可能會導致解碼器耗費大量 CPU 與記憶體資源。建議限制剖析資料的大小。
此模組為習慣標準函式庫 marshal 與 pickle 模組的使用者提供熟悉的 API。
對基本 Python 物件階層進行編碼:
>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print(json.dumps("\"foo\bar"))
"\"foo\bar"
>>> print(json.dumps('\u1234'))
"\u1234"
>>> print(json.dumps('\\'))
"\\"
>>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}
>>> from io import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'
改用緊湊型編碼方式:
>>> import json
>>> json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))
'[1,2,3,{"4":5,"6":7}]'
美化輸出:
>>> import json
>>> print(json.dumps({'6': 7, '4': 5}, sort_keys=True, indent=4))
{
"4": 5,
"6": 7
}
自訂 JSON 物件編碼方式:
>>> import json
>>> def custom_json(obj):
... if isinstance(obj, complex):
... return {'__complex__': True, 'real': obj.real, 'imag': obj.imag}
... raise TypeError(f'Cannot serialize object of {type(obj)}')
...
>>> json.dumps(1 + 2j, default=custom_json)
'{"__complex__": true, "real": 1.0, "imag": 2.0}'
JSON 解碼:
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
'"foo\x08ar'
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
['streaming API']
自訂 JSON 物件解碼方式:
>>> import json
>>> def as_complex(dct):
... if '__complex__' in dct:
... return complex(dct['real'], dct['imag'])
... return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
... object_hook=as_complex)
(1+2j)
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')
繼承 JSONEncoder 類別並自行擴充額外的編碼方法:
>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
... def default(self, obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... # Let the base class default method raise the TypeError
... return super().default(obj)
...
>>> json.dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[2.0', ', 1.0', ']']
在 shell 使用 json 來驗證和美化印出:
$ echo '{"json":"obj"}' | python -m json
{
"json": "obj"
}
$ echo '{1.2:3.4}' | python -m json
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
更詳盡的文件請見 命令列介面。
備註
JSON 語法是 YAML 1.2 語法的一種子集合。所以如果使用預設的設定的話(準確來說,使用預設的 separators 分隔符設定的話),這個模組的輸出也符合 YAML 1.0 和 1.1 的子集合規範。因此你也可以利用這個模組來當作 YAML 的序列化工具(serializer)。
備註
這個模組的編、解碼器預設會保存輸入與輸出資料的順序關係,除非一開始的輸入本身就是無序的。
基本用法¶
- json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)¶
參考這個 Python-to-JSON 轉換表將 obj 序列化為符合 JSON 格式的串流,並寫入到 fp (一個支援
.write()方法的 file-like object)備註
與
pickle和marshal不同,JSON 不具有二進位分框(binary framed)的協定,因此嘗試重複呼叫dump()來序列化多個物件到同一個 fp 裡將導致無效的 JSON 檔案。- 參數:
obj (object) -- 要被序列化的 Python 物件。
fp (file-like object) -- The file-like object obj will be serialized to. The
jsonmodule always producesstrobjects, notbytesobjects, thereforefp.write()must supportstrinput.skipkeys (bool) -- If
True, keys that are not of a basic type (str,int,float,bool,None) will be skipped instead of raising aTypeError. DefaultFalse.ensure_ascii (bool) -- If
True(the default), the output is guaranteed to have all incoming non-ASCII and non-printable characters escaped. IfFalse, all characters will be outputted as-is, except for the characters that must be escaped: quotation mark, reverse solidus, and the control characters U+0000 through U+001F.check_circular (bool) -- 如為
False,則針對不同容器型別的循環參照 (circular reference) 檢查將會被跳過,若有循環參照則最後將引發RecursionError(或其他更糟的錯誤)。預設為True。allow_nan (bool) -- 如為
False,則序列化不符合嚴格 JSON 規範的超出範圍float值 (nan,inf,-inf) 會引發ValueError。如為True(預設值),則將使用它們的 JavaScript 等效表示 (NaN,Infinity,-Infinity)。cls (a
JSONEncodersubclass) -- If set, a custom JSON encoder with thedefault()method overridden, for serializing into custom datatypes. IfNone(the default),JSONEncoderis used.indent (int | str | None) -- If a positive integer or string, JSON array elements and object members will be pretty-printed with that indent level. A positive integer indents that many spaces per level; a string (such as
"\t") is used to indent each level. If zero, negative, or""(the empty string), only newlines are inserted. IfNone(the default), the most compact representation is used.separators (tuple | None) -- 一個二元組:
(item_separator, key_separator)。如為None(預設值)則 separators 被預設為(', ', ': '),否則預設為(',', ': ')。想要獲得最緊湊的 JSON 表示形式,你可以指定(',', ':')來消除空格。default (callable | None) -- A function that is called for objects that can't otherwise be serialized. It should return a JSON encodable version of the object or raise a
TypeError. IfNone(the default),TypeErroris raised.