给定下面的代码示例,如何使用Python3用JSON序列化这些类实例?
class TreeNode():
def __init__(self, name):
self.name = name
self.children = []
当我尝试执行json.dumps
时,会出现以下错误:
TypeError: <TreeNode object at 0x7f6sf4276f60> is not JSON serializable
然后我发现,如果我将默认值设置为json.dumps
以返回__dict__
,我可以很好地序列化它,但执行json.loads
就成了一个问题。
我可以找到很多带有基本字符串的自定义编码器/解码器示例,但是没有一个示例有列表,在本例中是self.children。子节点列表将包含子节点及其子节点其他节点。我需要一种方法来得到所有的一切。
因为您处理的是树结构,所以使用嵌套字典是很自然的。下面的代码片段创建了一个
dict
的子类,并将自己用作实例的底层__dict__
,这是我在许多不同上下文中遇到的一个有趣而有用的技巧:Is it preferable to return an anonymous class or an object to use as a 'struct'?(stackoverflow)
How to use a dot “.” to access members of dictionary?(stackoverflow)
jsobject.py (PyDoc.net)
Making Python Objects that act like Javascript Objects (詹姆斯·罗伯特的博客)
AttrDict (ActiveState配方)
Dictionary with attribute-style access (ActiveState配方)
……事实上,我常常认为这是一个(不太出名的)Python习惯用法。
这解决了一半的序列化问题,但是当生成的数据用
json.loads()
读回时,它将是一个常规字典对象,而不是TreeNode
的实例。这是因为JSONEncoder
可以对字典(及其子类)本身进行编码。解决这个问题的一种方法是向
TreeNode
类添加一个可选的构造函数方法,该类可被调用以从json.loads()
返回的嵌套字典中重建数据结构。我的意思是:
输出:
这里有一个替代的答案,基本上是Python 3版本的my answer对问题Making object JSON serializable with regular encoder的回答,这个问题可以pickle常规的
json
编码器尚未处理的任何Python对象。有一些不同。其一,它不会对
json
模块进行monkey修补,因为这不是解决方案的基本部分。另一个是,尽管这次TreeNode
类不是从dict
类派生的,但它的功能基本上是相同的。这样做是为了防止stockJSONEncoder
对其进行编码,并导致使用JSONEncoder
子类中的_default()
方法。除此之外,它是一种非常通用的方法,并且能够处理许多其他类型的Python对象,包括用户定义的类,而无需修改。
输出:
相关问题 更多 >
编程相关推荐