问题描述:

Python内置的json模块提供了非常完善的Python对象到JSON格式的转换。

json.dumps()         #将Python中的对象转换为JSON中的字符串对象
json.loads()         #将JSON中的字符串对象转换为Python中的对象

这个问题是由于json.dumps()函数引起的。dumps是将dict数据转化为str数据,但是dict数据中包含byte、int、float、datetime等等的时候,数据所以会报错。

可能会遇到TypeError: Object of type xxx is not JSON serializable错误,也就是无法序列化某些对象格式。

注意:json默认支持的类型只有下面几种,其他的类型,比如自定义的类或者date类型,都需要自定义jsonEncoder。

    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          |
    +-------------------+---------------+

解决办法:

默认的编码函数很多数据类型都不能编码,自定义序列化,因此可以自己写一个Myencoder去继承json.JSONEncoder,具体如下:

1.MyEncoder.py

import json
class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            print("MyEncoder-datetime.datetime")
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        if isinstance(obj, bytes):
            return str(obj, encoding='utf-8')
        if isinstance(obj, int):
            return int(obj)
        elif isinstance(obj, float):
            return float(obj)
        #elif isinstance(obj, array):
        #    return obj.tolist()
        else:
            return super(MyEncoder, self).default(obj)

然后

第一步:

from MyEncoder import MyEncoder

然后在调用json.dump/dumps时,指定使用自定义序列化方法

json.dumps(data)改写为json.dumps(data,cls=MyEncoder,indent=4)

json.dumps(data,cls=MyEncoder,indent=4)

附上其他的字典dict互转JSON的方法

dict to json

def dict_to_json(dict_obj,name, Mycls = None):
    
    js_obj = json.dumps(dict_obj, cls = Mycls, indent=4)
    
    with open(name, 'w') as file_obj:
        file_obj.write(js_obj)

json to dict

def json_to_dict(filepath, Mycls = None):
    with open(filepath,'r') as js_obj:
        dict_obj = json.load(js_obj, cls = Mycls)
    return dict_obj

知识点:

不同的编程语言有不同的数据类型; 比如说:

Python的数据类型有(dict、list、string、int、float、long、bool、None)
Java的数据类型有(bool、char、byte、short、int、long、float、double)
C的数据类型有(bit、bool、char、int、short、long、unsigned、double、float)
Tcl的数据类型(int、bool、float、string)
Ruby的数据类型(Number、String、Ranges、Symbols、true、false、Array、Hash)

...
他们的共同特点是,都有字符串类型!
所以要实现不同的编程语言之间对象的传递,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。
JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

JSON类型            Python类型
{}                  dict
[]                  list
"string"            str
1234.56             int或float
true                True
false               False
null                None

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐