如何使一个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
当前回答
解决这个问题有很多方法。'ObjDict' (pip install object)是另一个。重点是提供像javascript一样的对象,它也可以像字典一样最好地处理从JSON加载的数据,但还有其他功能也很有用。这为原始问题提供了另一种解决方案。
其他回答
你知道预期产量是多少吗?例如,这个可以吗?
>>> f = FileItem("/foo/bar")
>>> magic(f)
'{"fname": "/foo/bar"}'
在这种情况下,你只需调用json.dumps(f.__dict__)。
如果您想要更多自定义输出,那么您必须继承JSONEncoder并实现您自己的自定义序列化。
对于一个简单的例子,请参见下面。
>>> from json import JSONEncoder
>>> class MyEncoder(JSONEncoder):
def default(self, o):
return o.__dict__
>>> MyEncoder().encode(f)
'{"fname": "/foo/bar"}'
然后你把这个类作为cls kwarg传递给json.dumps()方法:
json.dumps(cls=MyEncoder)
如果还想解码,则必须向JSONDecoder类提供一个自定义object_hook。例如:
>>> def from_json(json_object):
if 'fname' in json_object:
return FileItem(json_object['fname'])
>>> f = JSONDecoder(object_hook = from_json).decode('{"fname": "/foo/bar"}')
>>> f
<__main__.FileItem object at 0x9337fac>
>>>
这是一个小库,它将一个对象及其所有子对象序列化为JSON,并将其解析回来:
https://github.com/tobiasholler/PyJSONSerialization/
我最喜欢Lost Koder的方法。当我试图序列化成员/方法不可序列化的更复杂的对象时,我遇到了问题。这是我的实现,工作在更多的对象:
class Serializer(object):
@staticmethod
def serialize(obj):
def check(o):
for k, v in o.__dict__.items():
try:
_ = json.dumps(v)
o.__dict__[k] = v
except TypeError:
o.__dict__[k] = str(v)
return o
return json.dumps(check(obj).__dict__, indent=2)
Jsonweb似乎是我的最佳解决方案。参见http://www.jsonweb.info/en/latest/
from jsonweb.encode import to_object, dumper
@to_object()
class DataModel(object):
def __init__(self, id, value):
self.id = id
self.value = value
>>> data = DataModel(5, "foo")
>>> dumper(data)
'{"__type__": "DataModel", "id": 5, "value": "foo"}'
任何人都想在没有外部库的情况下使用基本转换,这只是如何使用以下方式覆盖自定义类的__iter__ & __str__函数。
class JSONCustomEncoder(json.JSONEncoder):
def default(self, obj):
return obj.__dict__
class Student:
def __init__(self, name: str, slug: str):
self.name = name
self.age = age
def __iter__(self):
yield from {
"name": self.name,
"age": self.age,
}.items()
def __str__(self):
return json.dumps(
self.__dict__, cls=JSONCustomEncoder, ensure_ascii=False
)
通过在dict()中进行包装来使用该对象,从而保留数据。
s = Student("aman", 24)
dict(s)