如何使一个Python类序列化?

class FileItem:
    def __init__(self, fname):
        self.fname = fname

尝试序列化为JSON:

>>> import json
>>> x = FileItem('/foo/bar')
>>> json.dumps(x)
TypeError: Object of type 'FileItem' is not JSON serializable

当前回答

如果你正在使用Python3.5+,你可以使用jsons。(PyPi: https://pypi.org/project/jsons/)它将把你的对象(及其所有属性递归地)转换为字典。

import jsons

a_dict = jsons.dump(your_object)

或者如果你想要一个字符串:

a_str = jsons.dumps(your_object)

或者你的类实现了jsons。JsonSerializable:

a_dict = your_object.json

其他回答

这个函数使用递归迭代遍历字典的每个部分,然后调用非内置类型类的repr()方法。

def sterilize(obj):
    object_type = type(obj)
    if isinstance(obj, dict):
        return {k: sterilize(v) for k, v in obj.items()}
    elif object_type in (list, tuple):
        return [sterilize(v) for v in obj]
    elif object_type in (str, int, bool, float):
        return obj
    else:
        return obj.__repr__()

我选择使用装饰器来解决datetime对象序列化问题。 这是我的代码:

#myjson.py
#Author: jmooremcc 7/16/2017

import json
from datetime import datetime, date, time, timedelta
"""
This module uses decorators to serialize date objects using json
The filename is myjson.py
In another module you simply add the following import statement:
    from myjson import json

json.dumps and json.dump will then correctly serialize datetime and date 
objects
"""

def json_serial(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, (datetime, date)):
        serial = str(obj)
        return serial
    raise TypeError ("Type %s not serializable" % type(obj))


def FixDumps(fn):
    def hook(obj):
        return fn(obj, default=json_serial)

    return hook

def FixDump(fn):
    def hook(obj, fp):
        return fn(obj,fp, default=json_serial)

    return hook


json.dumps=FixDumps(json.dumps)
json.dump=FixDump(json.dump)


if __name__=="__main__":
    today=datetime.now()
    data={'atime':today, 'greet':'Hello'}
    str=json.dumps(data)
    print str

通过导入上述模块,我的其他模块以正常的方式(没有指定默认关键字)使用json来序列化包含日期时间对象的数据。datetime序列化器代码会自动为json调用。Dumps和json.dump。

解决这个问题有很多方法。'ObjDict' (pip install object)是另一个。重点是提供像javascript一样的对象,它也可以像字典一样最好地处理从JSON加载的数据,但还有其他功能也很有用。这为原始问题提供了另一种解决方案。

除了Onur的答案,你可能想要处理如下的datetime类型。(以便处理:'datetime. time.)Datetime对象没有属性dict异常。)

def datetime_option(value):
    if isinstance(value, datetime.date):
        return value.timestamp()
    else:
        return value.__dict__

用法:

def toJSON(self):
    return json.dumps(self, default=datetime_option, sort_keys=True, indent=4)

正如在许多其他答案中提到的,您可以将函数传递给json。转储将不是默认支持的类型之一的对象转换为受支持的类型。令人惊讶的是,他们都没有提到最简单的情况,即使用内置函数vars将对象转换为包含其所有属性的dict:

json.dumps(obj, default=vars)

注意,这只涵盖了基本的情况,如果你需要对某些类型进行更具体的序列化(例如排除某些属性或没有__dict__属性的对象),你需要使用自定义函数或JSONEncoder,如其他答案中所述。