2010-09-09 59 views
5

我很新的python(我使用Python 3),我試圖序列化一個字符串和兩個列表作爲JSon成員的類。我發現python standart中有一個json庫,但似乎需要手動實現序列化方法。是否有一個JSon編碼器,我可以簡單地傳遞一個對象,並以字符串的形式接收序列化對象,而無需實現序列化方法。 例如:簡單的JSON編碼與Python

class MyClass: 
    pass 

if __name__ == '__main__': 
    my_name = "me" 
    my_list = {"one","two"} 
    my_obj = MyClass() 
    my_obj.name = my_name; 
    my_obj.my_list = my_list 


    serialized_object = JSONserializer.serialize(my_obj). 

謝謝。

+0

Python版本是否重要?我的意思是,你能用2.x做到這一點嗎,但是無法在3.0中做到這一點? – esylvestre 2010-09-09 18:10:50

+0

是的,大多數庫似乎已經從2.x更改爲3. – 2010-09-09 18:21:39

回答

3

不知道任何事情預先構建的,但你可以寫一個,如果你的對象是很簡單。重寫JSONEncoder中的默認方法以查看inspect.getmembers(obj)(檢查是獲取__dict__中屬性集的更可讀的方法)。

#!/usr/bin/env python3 

import inspect 
from json import JSONEncoder 


class TreeNode: 

    def __init__(self, value, left=None, right=None): 
     self.value = value 
     self.left = left 
     self.right = right 


class ObjectJSONEncoder(JSONEncoder): 

    def default(self, reject): 
     is_not_method = lambda o: not inspect.isroutine(o) 
     non_methods = inspect.getmembers(reject, is_not_method) 
     return {attr: value for attr, value in non_methods 
       if not attr.startswith('__')} 


if __name__ == '__main__': 
    tree = TreeNode(42, 
     TreeNode(24), 
     TreeNode(242), 
    ) 
    print(ObjectJSONEncoder().encode(tree)) 

更新: @Alexandre德尚說isroutine作品比對某些輸入法。

+0

謝謝你的支持者,除了兩件事外,它幾乎可以做到這一點。 is_not_method = lambda o:not inspect.ismethod(o)似乎也需要not inspect.isroutine(o)語句。它看起來像在Python中內置的方法是一個極限情況。另外,我的課程需要一個可以序列化的列表。它看起來像列表中的元素不會被序列化。 – 2010-09-10 18:08:37

+0

@Alexandre Deschamps:我不知道你是什麼意思......如果你將'__main__'中的這些數字改爲數字列表,那麼它序列化就好了。 – cdleary 2010-09-10 20:53:35

+0

好吧,我剛剛發現我是問題所在。我使用{}而不是[]來創建列表。正如我所說,我對這門語言很陌生。它工作正常。只要將「not inspect.isroutine」添加到您的示例中,以防其他人需要它。非常感謝您的時間。 – 2010-09-10 21:38:54

0

JSONEncoder這個班怎麼樣?

更新

我一定跳過了有關數據的一部分被包含在一個類中。如果你想在不需要擴展編碼器的情況下完成任意Python對象的序列化,那麼也許你可以使用picklejson的組合。酸洗時,使用protocol = 0將數據序列化爲可讀的ASCII。

+0

不過,我需要編碼一個類,而不僅僅是一個簡單的類型或數組。這個類似乎需要一個手動定義的序列化方法來序列化一個類。也許我錯了,因爲我對這門語言很陌生,但是當我測試時,我就是這樣。 – 2010-09-09 18:28:32

+0

@Alexandre - 更新了我的答案 – 2010-09-09 18:53:51

+0

'人類可讀的pickle'的想法是:'(i__main__ 地圖 P0 (DP1 S'towers' P2 (LP3 (i__main__ 塔 P4 (DP5 S'attack ' P6 I10 sbasS'creeps' P7 (LP8在列表' P9 S'one串蠕變asb.'相比JSON,即幾乎不人類可讀的。 – Pat 2012-03-29 02:14:02

4

您如何期待json庫知道如何序列化任意類?

在你的情況,如果你的類是很簡單的,你也許可以逃脫喜歡的東西

foo = FooObject() # or whatever 
json_string = json.dumps(foo.__dict__) 

只序列化對象的成員。然後

反序列化將需要像

foo_data = json.loads(json_string) 
foo = FooObject(**foo_data) 
+0

那不,似乎不工作,因爲我的班級有兩個成員,這是一個字符串和字符串列表 – 2010-09-10 18:05:30

+0

它適用於我:http://gist.github.com/574291。如果你的對象真的只有兩個成員,一個字符串和一個字符串列表,那麼序列化將起作用。我使用的反序列化技術依賴於你的對象的'__init__'函數來獲取與成員相同名稱的參數。查看上面的要點來了解一個工作示例。 – 2010-09-10 20:13:04

+0

@WillMcCutchen感謝您使用'dict'的靈感。我想做類似的事情,雖然我的對象(來自SOAP請求)沒有'__dict__'方法,調用'dict(soapObj)'給了我一個很好的打印的JSON字符串。我也是Python新手,這不是一個明顯的技術,所以我很高興你提到它! – Pat 2012-03-29 02:05:17