繁体   English   中英

如何使用JSON序列化对象

[英]How to serialize objects with json

ChildParent类都继承自Python字典:

import json 

class Child(dict):
    def __init__(self, **kwargs):
        super(Child, self).__init__(**kwargs)

class Parent(dict):
    def __init__(self, **kwargs):
        super(Parent, self).__init__(**kwargs)

parent = Parent(child = Child())

print type(parent['child'])

打印:

<class '__main__.Child'>

使用json.dumpsjson.loads执行序列化和反序列化json.loadsParent['child']成为常规词典:

dumped = json.dumps(parent)
loaded = json.loads(dumped)
parent_2 = Parent(**loaded)
print type(parent_2['child'])

打印:

<type 'dict'>

问题:如何确保序列化后, parent_2['child']Child的实例,而不是常规的Python字典?

loads创建字典,仅此而已。 经过一番尝试和错误后,我发现了它。 (注意:您似乎正在使用旧版Python,因此可能需要对该解决方案进行一些语法调整。)

import json


class Child(dict):
    def __init__(self, **kwargs):
        super(Child, self).__init__(**kwargs)


class Parent(dict):
    def __init__(self, **kwargs):
        super(Parent, self).__init__(**kwargs)


parent = Parent(child=Child())

print(type(parent['child']))

if __name__ == '__main__':
    dumped = json.dumps(parent)
    loaded = json.loads(dumped)
    parent_2 = Parent(child=Child(**loaded)) # Changed how you call Parent
    print(type(parent_2['child']))

如果不使用初始化为Childdict调用Parent的args,我们将无法期望检测到Child类型, 除非您添加其他逻辑来检测该类型。

你可以用泡菜 解开未知的腌制对象可能很危险(因为它们可能是恶意的)。

阅读文档https://docs.python.org/3/library/pickle.html,因为它包含更多信息。

import pickle
class Foo:
    attr = 'A class attribute'


with open('pickle_class.pk','wb') as f:
         pickle.dump(Foo,f)   

# we open the file for reading
with open('pickle_class.pk','rb') as f:

    Bar = pickle.load(f)

# Test if they are the same.
assert Bar==Foo,'Not the Same'

您也可以压缩。

import bz2
import pickle

with bz2.BZ2File('pickled_class', 'wb') as f:
    pickle.dump(Foo, s)

在某些情况下,使用多线程和lambda时,第三方模块dill可以很容易地被腌制

PicklingError: Can't pickle <function <lambda> at 0x111d0a7b8>: attribute lookup <lambda> on __main__ failed

流程和危险(破坏恶意软件)是相同的:

import dill

class Foo:
    attr = 'A class attribute'

with open('pickle_class.pk','wb') as f:
    dill.dump(Foo,f) 

阅读莳萝文档: https : //pypi.org/project/dill/

注意:永远不会加载未知的腌制文件

有一个名为jsonpickle的软件包。 似乎可以解决问题;

import json
import jsonpickle

class Child(dict):
    def __init__(self, **kwargs):
        super(Child, self).__init__(**kwargs)

class Parent(dict):
    def __init__(self, **kwargs):
        super(Parent, self).__init__(**kwargs)

if __name__ == '__main__':
    parent = Parent(child=Child())
    dumped = jsonpickle.encode(parent)
    loaded = jsonpickle.decode(dumped)
    parent_2 = Parent(**loaded)
    print(type(parent_2['child']))

<class '__main__.Child'>

注意; 为此,Json将获得有关原始对象图的信息,以便可以对其进行还原。

('{"py/object": "__main__.Parent", "child": {"py/object": "__main__.Child", '
 '"__dict__": {}}, "__dict__": {}}')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM