Python 如何使类 JSON 可序列化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3768895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make a class JSON serializable
提问by Sergey
How to make a Python class serializable?
如何使 Python 类可序列化?
A simple class:
一个简单的类:
class FileItem:
def __init__(self, fname):
self.fname = fname
What should I do to be able to get output of:
我应该怎么做才能获得以下输出:
>>> import json
>>> my_file = FileItem('/foo/bar')
>>> json.dumps(my_file)
TypeError: Object of type 'FileItem' is not JSON serializable
Without the error
没有错误
采纳答案by Manoj Govindan
Do you have an idea about the expected output? For e.g. will this do?
你知道预期的输出吗?例如,这可以吗?
>>> f = FileItem("/foo/bar")
>>> magic(f)
'{"fname": "/foo/bar"}'
In that case you can merely call json.dumps(f.__dict__).
在这种情况下,您只能调用json.dumps(f.__dict__).
If you want more customized output then you will have to subclass JSONEncoderand implement your own custom serialization.
如果您想要更多定制的输出,那么您将不得不子类化JSONEncoder并实现您自己的定制序列化。
For a trivial example, see below.
有关一个简单的示例,请参见下文。
>>> from json import JSONEncoder
>>> class MyEncoder(JSONEncoder):
def default(self, o):
return o.__dict__
>>> MyEncoder().encode(f)
'{"fname": "/foo/bar"}'
Then you pass this class into the json.dumps()method as clskwarg:
然后你将这个类json.dumps()作为clskwarg传递给方法:
json.dumps(cls=MyEncoder)
If you also want to decode then you'll have to supply a custom object_hookto the JSONDecoderclass. For e.g.
如果你也想解码,那么你将有一个自定义供应object_hook给JSONDecoder类。例如
>>> 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>
>>>
回答by gecco
For more complex classes you could consider the tool jsonpickle:
对于更复杂的类,您可以考虑使用jsonpickle工具:
jsonpickle is a Python library for serialization and deserialization of complex Python objects to and from JSON.
The standard Python libraries for encoding Python into JSON, such as the stdlib's json, simplejson, and demjson, can only handle Python primitives that have a direct JSON equivalent (e.g. dicts, lists, strings, ints, etc.). jsonpickle builds on top of these libraries and allows more complex data structures to be serialized to JSON. jsonpickle is highly configurable and extendable–allowing the user to choose the JSON backend and add additional backends.
jsonpickle 是一个 Python 库,用于将复杂的 Python 对象与 JSON 进行序列化和反序列化。
用于将 Python 编码为 JSON 的标准 Python 库,例如 stdlib 的 json、simplejson 和 demjson,只能处理具有直接 JSON 等效项的 Python 原语(例如,dicts、lists、strings、ints 等)。jsonpickle 构建在这些库之上,并允许将更复杂的数据结构序列化为 JSON。jsonpickle 是高度可配置和可扩展的——允许用户选择 JSON 后端并添加额外的后端。
回答by Paulo Freitas
Another option is to wrap JSON dumping in its own class:
另一种选择是将 JSON 转储包装在它自己的类中:
import json
class FileItem:
def __init__(self, fname):
self.fname = fname
def __repr__(self):
return json.dumps(self.__dict__)
Or, even better, subclassing FileItem class from a JsonSerializableclass:
或者,更好的是,从类继承 FileItemJsonSerializable类:
import json
class JsonSerializable(object):
def toJson(self):
return json.dumps(self.__dict__)
def __repr__(self):
return self.toJson()
class FileItem(JsonSerializable):
def __init__(self, fname):
self.fname = fname
Testing:
测试:
>>> f = FileItem('/foo/bar')
>>> f.toJson()
'{"fname": "/foo/bar"}'
>>> f
'{"fname": "/foo/bar"}'
>>> str(f) # string coercion
'{"fname": "/foo/bar"}'
回答by Onur Y?ld?r?m
Here is a simple solution for a simple feature:
这是一个简单功能的简单解决方案:
.toJSON()Method
.toJSON()方法
Instead of a JSON serializable class, implement a serializer method:
实现序列化器方法而不是 JSON 可序列化类:
import json
class Object:
def toJSON(self):
return json.dumps(self, default=lambda o: o.__dict__,
sort_keys=True, indent=4)
So you just call it to serialize:
所以你只需调用它来序列化:
me = Object()
me.name = "Onur"
me.age = 35
me.dog = Object()
me.dog.name = "Apollo"
print(me.toJSON())
will output:
将输出:
{
"age": 35,
"dog": {
"name": "Apollo"
},
"name": "Onur"
}
回答by Dan Brough
Here is my 3 cents ...
This demonstrates explicit json serialization for a tree-like python object.
Note: If you actually wanted some code like this you could use the twisted
FilePathclass.
这是我的 3 美分......
这演示了树状 python 对象的显式 json 序列化。
注意:如果你真的想要一些这样的代码,你可以使用扭曲的 FilePath类。
import json, sys, os
class File:
def __init__(self, path):
self.path = path
def isdir(self):
return os.path.isdir(self.path)
def isfile(self):
return os.path.isfile(self.path)
def children(self):
return [File(os.path.join(self.path, f))
for f in os.listdir(self.path)]
def getsize(self):
return os.path.getsize(self.path)
def getModificationTime(self):
return os.path.getmtime(self.path)
def _default(o):
d = {}
d['path'] = o.path
d['isFile'] = o.isfile()
d['isDir'] = o.isdir()
d['mtime'] = int(o.getModificationTime())
d['size'] = o.getsize() if o.isfile() else 0
if o.isdir(): d['children'] = o.children()
return d
folder = os.path.abspath('.')
json.dump(File(folder), sys.stdout, default=_default)
回答by Tobi
This is a small library that serializes an object with all its children to JSON and also parses it back:
这是一个小型库,它将一个对象及其所有子对象序列化为 JSON 并将其解析回:
回答by matthewlent
jsonweb seems to be the best solution for me. See http://www.jsonweb.info/en/latest/
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"}'
回答by Jason S
I like Onur's answerbut would expand to include an optional toJSON()method for objects to serialize themselves:
我喜欢Onur 的答案,但会扩展为包含一个可选toJSON()的对象序列化方法:
def dumper(obj):
try:
return obj.toJSON()
except:
return obj.__dict__
print json.dumps(some_big_object, default=dumper, indent=2)
回答by Dewsworld
I came up with my own solution. Use this method, pass any document (dict,list, ObjectIdetc) to serialize.
我想出了我自己的解决方案。使用此方法,传递任何文档(dict、list、ObjectId等)以进行序列化。
def getSerializable(doc):
# check if it's a list
if isinstance(doc, list):
for i, val in enumerate(doc):
doc[i] = getSerializable(doc[i])
return doc
# check if it's a dict
if isinstance(doc, dict):
for key in doc.keys():
doc[key] = getSerializable(doc[key])
return doc
# Process ObjectId
if isinstance(doc, ObjectId):
doc = str(doc)
return doc
# Use any other custom serializting stuff here...
# For the rest of stuff
return doc
回答by tryer3000
import simplejson
class User(object):
def __init__(self, name, mail):
self.name = name
self.mail = mail
def _asdict(self):
return self.__dict__
print(simplejson.dumps(User('alice', '[email protected]')))
if use standard json, u need to define a defaultfunction
如果使用标准json,你需要定义一个default函数
import json
def default(o):
return o._asdict()
print(json.dumps(User('alice', '[email protected]'), default=default))

