簡體   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