1 2 3 4

8 json序列化以及序列化非默认类型

1 简介

json格式(JavaScript Object Notation的缩写)是一种用于交换数据的文本格式。每个JSON对象,就是一个值。

要么是简单类型的值,要么是复合类型的值,但是只能是一个值,不能是两个或更多的值。这就是说,每个JSON文档只能包含一个值。

2 JSON对值的类型和格式的规定

 1. 支持类型 :dict |list| int |float| bool| str| null
 2. 支持格式 :{}和[]的组合,{}存放双列信息(类比字典) ,[]存放单列信息(类比列表)
 3. {}的key必须是字符串,并且用""包裹(双引号)
 4. 字符串必须使用双引号表示,不能使用单引号。
 5. 对象的键名必须放在双引号里面。
 6. 数组或对象最后一个成员的后面,不能加逗号。 

  

3 序列化与反序列化

序列化          将对象转化为字符串

反序列化      将字符串转化为对象

# 序列化:将对象转换为字符串
#json.dumps():  将 Python 对象编码成 JSON 字符串
# json.dump():  将Python对象序列化为json字符串后写入文件
obj = {'name': 'Owen', "age": 18, 'height': 180, "gender": "男"}
r1 = json.dumps(obj, ensure_ascii=False)  # 取消默认ascii编码,同该文件的编码 utf-8 py3默认,py2规定文件头
print(r1)
# {"name": "Owen", "age": 18, "height": 180, "gender": "男"}
 
 
with open('1.txt','w',encoding='utf-8') as wf: # 若没有1.txt会创建
    json.dump(obj,wf,ensure_ascii=False)
# 将转化后的json字符串{"name": "Owen", "age": 18, "height": 180, "gender": "男"}写入1.txt中
 
 
# 反序列化:将字符串转换为对象
# json.load()    读取文件中json形式的字符串元素转化为Python对象
# json.loads()   将已编码的 JSON 字符串解码为 Python 对象
 
json_str = '{"name": "Owen", "age": 18, "height": 180, "gender": "男"}'
r2 = json.loads(json_str, encoding='utf-8')  # 默认跟当前文件被解释器执行的编码走
print(r2, type(r2))
 
with open('1.txt', 'r', encoding='utf-8') as rf:
    r3 = json.load(rf)
    print(r3, type(r3))

4  python与json的对应关系

可以在json.JSONEncoder找到源码

"""Extensible JSON <http://json.org> encoder for Python data structures.

Supports the following objects and types by default:

+-------------------+---------------+
| Python | JSON |
+===================+===============+
| dict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
| str | string |
+-------------------+---------------+
| int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
| False | false |
+-------------------+---------------+
| None | null |
+-------------------+---------------+

To extend this to recognize other objects, subclass and implement a
``.default()`` method with another method that returns a serializable
object for ``o`` if possible, otherwise it should call the superclass
implementation (to raise ``TypeError``).

"""

5 json序列化本不支持的类型

有两种方式  第一种就是将不支持的类型转换为json支持的类型  第二种就是源码当中告知的继承源码中的类 自己重写一个类 

案例

import json

from datetime import datetime,date


res = {'c1':datetime.now(),'c2':date.today()}
# print(json.dumps(res)) # 报错如下

'''
报错
in default
    o.__class__.__name__)
    
TypeError: Object of type 'datetime' is not JSON serializable
'''

'''
源码
def 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):

  def default(self, o):
 
        raise TypeError("Object of type '%s' is not JSON serializable" %
                        o.__class__.__name__)


'''


'''
通过源码可知 主要的default方法报的错 那么只需要重写default方法 实现自己想要的
然的功能  然后继承json.JSONEncoder就可以了
'''

class MyJson(json.JSONEncoder):
    def default(self, o):
        if isinstance(o,datetime):
            return o.strftime(("%Y-%m-%d %X"))
        elif isinstance(o,date):
            return o.strftime(("%Y-%m-%d"))
        else:
            return super().default(self,o)

res = {'c1':datetime.now(),'c2':date.today()}
print(json.dumps(res,cls=MyJson))

# {"c1": "2021-03-04 22:49:38", "c2": "2021-03-04"}

  

 

posted @ 2021-03-04 22:54  犹豫就会拜佛  阅读(366)  评论(0编辑  收藏  举报