如何使一个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
如何使一个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
当前回答
要添加另一个选项:您可以使用attrs包和asdict方法。
class ObjectEncoder(JSONEncoder):
def default(self, o):
return attr.asdict(o)
json.dumps(objects, cls=ObjectEncoder)
然后再转换回去
def from_json(o):
if '_obj_name' in o:
type_ = o['_obj_name']
del o['_obj_name']
return globals()[type_](**o)
else:
return o
data = JSONDecoder(object_hook=from_json).decode(data)
类看起来像这样
@attr.s
class Foo(object):
x = attr.ib()
_obj_name = attr.ib(init=False, default='Foo')
其他回答
这对我来说很有效:
class JsonSerializable(object):
def serialize(self):
return json.dumps(self.__dict__)
def __repr__(self):
return self.serialize()
@staticmethod
def dumper(obj):
if "serialize" in dir(obj):
return obj.serialize()
return obj.__dict__
然后
class FileItem(JsonSerializable):
...
and
log.debug(json.dumps(<my object>, default=JsonSerializable.dumper, indent=2))
我喜欢Onur的答案,但会扩展到包括一个可选的toJSON()方法,用于对象序列化自己:
def dumper(obj):
try:
return obj.toJSON()
except:
return obj.__dict__
print json.dumps(some_big_object, default=dumper, indent=2)
一个非常简单的一行程序解决方案
import json
json.dumps(your_object, default=lambda __o: __o.__dict__)
结束!
下面是一个测试。
import json
from dataclasses import dataclass
@dataclass
class Company:
id: int
name: str
@dataclass
class User:
id: int
name: str
email: str
company: Company
company = Company(id=1, name="Example Ltd")
user = User(id=1, name="John Doe", email="john@doe.net", company=company)
json.dumps(user, default=lambda __o: __o.__dict__)
输出:
{
"id": 1,
"name": "John Doe",
"email": "john@doe.net",
"company": {
"id": 1,
"name": "Example Ltd"
}
}
正如在许多其他答案中提到的,您可以将函数传递给json。转储将不是默认支持的类型之一的对象转换为受支持的类型。令人惊讶的是,他们都没有提到最简单的情况,即使用内置函数vars将对象转换为包含其所有属性的dict:
json.dumps(obj, default=vars)
注意,这只涵盖了基本的情况,如果你需要对某些类型进行更具体的序列化(例如排除某些属性或没有__dict__属性的对象),你需要使用自定义函数或JSONEncoder,如其他答案中所述。
解决这个问题有很多方法。'ObjDict' (pip install object)是另一个。重点是提供像javascript一样的对象,它也可以像字典一样最好地处理从JSON加载的数据,但还有其他功能也很有用。这为原始问题提供了另一种解决方案。