使用 simplejson 序列化简单类对象的最简单方法?
我正在尝试使用 JSON (使用 simplejson)序列化 python 对象列表,但收到该对象“不可 JSON 可序列化”的错误。
该类是一个简单的类,其字段仅为整数、字符串和浮点数,并且从一个父超类继承类似的字段,例如:
class ParentClass:
def __init__(self, foo):
self.foo = foo
class ChildClass(ParentClass):
def __init__(self, foo, bar):
ParentClass.__init__(self, foo)
self.bar = bar
bar1 = ChildClass(my_foo, my_bar)
bar2 = ChildClass(my_foo, my_bar)
my_list_of_objects = [bar1, bar2]
simplejson.dump(my_list_of_objects, my_filename)
其中 foo、bar 是我上面提到的简单类型。唯一棘手的事情是 ChildClass 有时有一个字段引用另一个对象(类型不是 ParentClass 或 ChildClass)。
使用 simplejson 将其序列化为 json 对象的最简单方法是什么?使其可序列化为字典就足够了吗?简单地为 ChildClass 编写一个 dict 方法是最好的方法吗?最后,拥有引用另一个对象的字段会使事情变得非常复杂吗?如果是这样,我可以重写我的代码,只在类中包含简单的字段(如字符串/浮点数等),
谢谢。
I'm trying to serialize a list of python objects with JSON (using simplejson) and am getting the error that the object "is not JSON serializable".
The class is a simple class having fields that are only integers, strings, and floats, and inherits similar fields from one parent superclass, e.g.:
class ParentClass:
def __init__(self, foo):
self.foo = foo
class ChildClass(ParentClass):
def __init__(self, foo, bar):
ParentClass.__init__(self, foo)
self.bar = bar
bar1 = ChildClass(my_foo, my_bar)
bar2 = ChildClass(my_foo, my_bar)
my_list_of_objects = [bar1, bar2]
simplejson.dump(my_list_of_objects, my_filename)
where foo, bar are simple types like I mentioned above. The only tricky thing is that ChildClass sometimes has a field that refers to another object (of a type that is not ParentClass or ChildClass).
What is the easiest way to serialize this as a json object with simplejson? Is it sufficient to make it serializable as a dictionary? Is the best way to simply write a dict method for ChildClass? Finally, does having the field that refer to another object significantly complicate things? If so, I can rewrite my code to only have simple fields in classes (like strings/floats etc.)
thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我过去使用过这种策略,并且对此非常满意:使用以下结构将自定义对象编码为 JSON 对象文字(如 Python
dict
s):这本质上是一个单项
dict
,其单个键是一个特殊字符串,指定编码的对象类型,其值是实例属性的dict
。如果这是有道理的话。编码器和解码器的一个非常简单的实现(从我实际使用的代码简化而来)如下所示:
在此实现中,假设您正在编码的对象将具有
from_dict()
类方法它知道如何从 JSON 解码的 dict 中重新创建实例。可以轻松扩展编码器和解码器以支持自定义类型(例如
datetime
对象)。编辑,回答您的编辑:这样的实现的好处是,它会自动编码和解码
TYPES
映射中找到的任何对象的实例。这意味着它将自动处理一个 ChildClass,如下所示:这应该会生成如下所示的 JSON:
I've used this strategy in the past and been pretty happy with it: Encode your custom objects as JSON object literals (like Python
dict
s) with the following structure:That's essentially a one-item
dict
whose single key is a special string that specifies what kind of object is encoded, and whose value is adict
of the instance's attributes. If that makes sense.A very simple implementation of an encoder and a decoder (simplified from code I've actually used) is like so:
In this implementation assumes that the objects you're encoding will have a
from_dict()
class method that knows how to take recreate an instance from adict
decoded from JSON.It's easy to expand the encoder and decoder to support custom types (e.g.
datetime
objects).EDIT, to answer your edit: The nice thing about an implementation like this is that it will automatically encode and decode instances of any object found in the
TYPES
mapping. That means that it will automatically handle a ChildClass like so:That should result in JSON something like the following:
借助以下函数,自定义类的实例可以表示为 JSON 格式的字符串:
函数将为
自定义类的实例
具有以下实例的字典
自定义类作为叶子,
类
An instance of a custom class could be represented as JSON formatted string with help of following function:
This function will produce JSON-formatted string for
an instance of a custom class,
a dictionary that have instances of
custom classes as leaves,
classes
正如 python 的 JSON 文档中所指定的 //
help(json.dumps)
// >您只需重写 JSONEncoder 的 default() 方法即可提供自定义类型转换,并将其作为 cls 参数传递。
这是我用来介绍 Mongo 的特殊数据类型(日期时间和 ObjectId)的一个方法,
调用它很简单
As specified in python's JSON docs //
help(json.dumps)
// >You should simply override the
default()
method ofJSONEncoder
in order to provide a custom type conversion, and pass it ascls
argument.Here is one I use to cover Mongo's special data types (datetime and ObjectId)
Calling it as simple as
如果您使用 Django,则可以通过 Django 的序列化器模块轻松完成。更多信息可以在这里找到: https://docs.djangoproject.com/en/dev /主题/序列化/
If you are using Django, it can be easily done via Django's serializers module. More info can be found here: https://docs.djangoproject.com/en/dev/topics/serialization/
这是一种黑客行为,我确信它可能有很多错误。但是,我正在生成一个简单的脚本,并且遇到了一个问题,即我不想子类化我的 json 序列化器来序列化模型对象列表。我最终使用列表理解
让:
资产=模型对象列表
代码:
到目前为止似乎可以很好地满足我的需求
This is kind of hackish and I'm sure there's probably a lot that can be wrong with it. However, I was producing a simple script and I ran the issue that I did not want to subclass my json serializer to serialize a list of model objects. I ended up using list comprehension
Let:
assets = list of modelobjects
Code:
So far seems to have worked charmingly for my needs
我有类似的问题,但我没有调用 json.dump 函数。
因此,要使
MyClass
JSON 可序列化而不为json.dump
提供自定义编码器,您必须对 json 编码器进行 Monkey 修补。首先在模块
my_module
中创建编码器:然后按照注释中的描述,猴子修补 json 编码器:
现在,甚至在外部调用
json.dump
库(您无法更改 cls 参数)将适用于您的 my_module.MyClass 对象。I have a similar problem but the
json.dump
function is not called by me.So, to make
MyClass
JSON serializable without giving a custom encoder tojson.dump
you have to Monkey patch the json encoder.First create your encoder in your module
my_module
:Then as it is described in the comment, monkey patch the json encoder:
Now, even an call of
json.dump
in an external library (where you cannot change thecls
parameter) will work for yourmy_module.MyClass
objects.我现在重读它时对我可能的两种解决方案感到有点愚蠢,
当然,当您使用 django-rest-framework 时,该框架针对上述问题内置了一些出色的功能。
请参阅其网站上的 此模型视图示例
如果您不使用 django-休息框架,无论如何这都会有所帮助:
我在本页中找到了针对此问题的 2 个有用的解决方案:(我最喜欢第二个!)
可能的解决方案 1(或可行的方法):
David Chambers Design 提出了一个很好的解决方案
我希望 David 不介意我复制粘贴他的解决方案代码在这里:
在实例的模型上定义序列化方法:
他甚至提取了上面的方法,因此它更具可读性:
请注意,这不是我的解决方案,所有积分都归于包含的链接。只是认为这应该是堆栈溢出。
这也可以在上面的答案中实现。
解决方案 2:
我的首选解决方案在此页面上找到:
http://www.traddicts.org/webdevelopment/flexible-and-simple-json-serialization-for-django/
顺便说一句,我看到了第二个也是最好的解决方案的作者:在 stackoverflow 上好吧:
Selaux
我希望他看到这一点,我们可以讨论开始在开放解决方案中实现和改进他的代码?
I feel a bit silly about my possible 2 solutions rereading it now,
of course when you use django-rest-framework, this framework have some excellent features buildin for this problem mentioned above.
see this model view example on their website
If you're not using django-rest-framework, this can help anyway:
I found 2 helpfull solutions for this problem in this page: (I like the second one the most!)
Possible solution 1 (or way to go):
David Chambers Design made a nice solution
I hope David does not mind I copy paste his solution code here:
Define a serialization method on the instance's model:
and he even extracted the method above, so it's more readable:
Please mind, it's not my solution, all the credits goes to the link included. Just thought this should be on stack overflow.
This could be implemented in the answers above as well.
Solution 2:
My preferable solution is found on this page:
http://www.traddicts.org/webdevelopment/flexible-and-simple-json-serialization-for-django/
By the way, i saw the writer of this second and best solution: is on stackoverflow as well:
Selaux
I hope he sees this, and we can talk about starting to implement and improve his code in an open solution?