Python3 dances with JSON

Introduction

In Python development, especially when it comes to web development, it is inevitable to deal with JSON (JavaScript Object Notation) . This article mainly tries to introduce how to use JSON in Python.

In the official documentation of Python 3, there are mainly 4 functions for JSON operations, which are json.dump(), json.load(), json.dumps()and json.loads(). json.dump()The function of and json.dumps()is to encode Python objects (encoder) and convert them into JSON format; and and , json.load()on json.loads()the contrary, decode (ecoder) the JSON format objects and convert them into Python objects.

The difference between json.dump() and json.dumps()

json.dump()and json.dumps()both function to serialize Python objects into JSON format. What is the difference? Let’s first look at the definitions of the two:

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)
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

The definitions of both are basically the same, but json.dump()there is one more fpparameter. The main difference between them is: json.dumps()serializes a Python object into a JSON-formatted string, and json.dump()serializes a Python object into a JSON-formatted stream. This stream can be written directly to a file or file-like object.

This may sound a bit confusing, so here’s an example:

>>> import json
>>> person = {
   
   "name":"dormouse", "age":40}
>>> json.dumps(person)
'{
   
   "name": "dormouse", "age": 40}'
>>> type(json.dumps(person))
<class 'str'>

As can be seen from the above example, json.dumps()a JSON formatted string is returned.

>>> from pathlib import Path
>>> with Path("/tmp/person.txt").open('w') as fp:
...     json.dump(person, fp)

The code in the above example generates a /tmp/person.txtfile named with the following contents: {"name": "dormouse", "age": 40}.

json.load()The difference with json.loads()is similar to .

coding

Serializing Python objects into JSON format objects is called encoding, mainly using the json.dump()and json.dumps()functions. According to what was mentioned above, these two functions are basically the same. The following mainly takes the json.dumps()function as an example. json.dump()The usage of the functions is basically similar.

json.dumps()Usage examples:

>>> import json
>>> person = {
   
   "name":"dormouse", "age":40, "blog":["blog1", "其他"]}
>>> json.dumps(person)
'{
   
   "name": "dormouse", "age": 40, "blog": ["blog1", "\\u5176\\u4ed6"]}'

The corresponding rules for encoding data types are as follows:

Python JSON
dict object
list, tuple array
str string
int, float, int- & float-derived Enums number
True true
False false
None null

Common parameters

json.dumps()There are many parameters that can be used with and json.dump(), here are some commonly used parameters:

ensure_ascii parameter

The default value of this parameter is Truethat non-ASCII characters will be escaped when encoding. For example, in the above example, the two
words "other" are encoded as \\u5176\\u4ed6. If this parameter is set to Fasle, then there will be no escaping. For example:

>>> json.dumps(person, ensure_ascii=False)
'{
   
   "name": "dormouse", "age": 40, "blog": ["blog1", "其他"]}'

indent parameter

This parameter controls the indentation of the encoding results. The default value is None. By default the encoding results are condensed together.
If this parameter is set to a positive integer or \t, it will make the encoding result more readable. For example:

>>> print(json.dumps(person, ensure_ascii=False, indent=4))
{
    "name": "dormouse",
    "age": 40,
    "blog": [
        "blog1",
        "其他"
    ]
}

sort_keys parameter

This parameter controls whether the encoding results are sorted by key value. The default value is False. If this parameter is set to Ture, then the dictionary keys of the encoding result will be sorted. Example:

>>> print(json.dumps(person, ensure_ascii=False, indent=4, sort_keys=True))
{
    "age": 40,
    "blog": [
        "blog1",
        "其他"
    ],
    "name": "dormouse"
}

For more parameters, please see: Python 3 official documentation

decoding

Converting a JSON format object to a Python object is called decoding, mainly using json.load()and
json.loads()functions. These two functions are essentially the same, with differences similar to json.dump()the and
json.dumps()functions. The following mainly takes json.loads()the function as an example, and json.load()
the usage of the function is basically similar.

json.loads()Usage examples:

>>> json.loads(json.dumps(person))
{
   
   'name': 'dormouse', 'age': 40, 'blog': ['blog1', '其他']}

The corresponding rules for decoding data types are as follows:

JSON Python
object dict
array list
string str
number (int) int
number (real) float
true True
false False
null None

Custom type processing

Sometimes, we need to deal with some custom types, such as the following class:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return "x:{}, y:{}".format(self.x, self.y)

When we want to encode its instance, an exception similar to the following will be generated (the file path is omitted):

>>> person = {
...    "name":"dormouse",
...    "point": Point(1,2)
}
>>> json.dumps(person)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File ".../lib/python3.6/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File ".../lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File ".../lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File ".../lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'Point' is not JSON serializable

The reason for the exception is that the JSON default method cannot encode such a Python object. So how to solve this problem? There are two main methods:

Use functions

def my_default(o):
    """ 自定义编码函数 """
    if isinstance(o, Point):
        return (o.x, o.y)
def my_hook(t):
    """ 自定义解码函数 """
    for k in t:
        if k == 'point':
            x, y = t[k]
            t[k] = Point(x, y)
    return t

# 编码
encode_str = json.dumps(person, default=my_default)
print(encode_str)
# 解码
decode_obj = json.loads(encode_str, object_hook=my_hook)
print(decode_obj)

The output is as follows:

{
   
   "name": "dormouse", "point": [1, 2]}
{
   
   'name': 'dormouse', 'point': x:1, y:2}

use class

class MyEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, Point):
            return (o.x, o.y)
        return json.JSONEncoder.default(o)
encode_str = json.dumps(person, cls=MyEncoder)
print(encode_str)

class MyDecoder(json.JSONDecoder):
    def decode(self, s):
        t = super().decode(s);
        for k in t:
            if k == 'point':
                x, y = t[k]
                t[k] = Point(x, y)
        return t
decode_obj = json.loads(encode_str, cls=MyDecoder)
print(decode_obj)

The output is as follows:

{
   
   "name": "dormouse", "point": [1, 2]}
{
   
   'name': 'dormouse', 'point': x:1, y:2}

References

  1. Official documentation for Python 3

Note:

The Python environment for this article is:

Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:51:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux

Guess you like

Origin blog.csdn.net/mouse2018/article/details/80703710