2010-11-03 95 views
3

有一個關於序列化我定義的類的問題。我有一些類,如在Python中序列化一個用戶定義的類

class Foo: 
    def __init__(self, x, y): 
      self.x = x, self.y = y 

    def toDict(self): 
      return dict(Foo = dict(x = self.x, y = self.y)) 

那麼可以包含多個FOOS,如類:

class Bar: 
    def __init__(self): 
      self.foos = [Foo(a, b), Foo(1, 2)] 

雖然這是真正的結構過於簡單化(它得到很多,遠不止嵌套),這是一個相當不錯的概述。實際的數據來自沒有任何實際結構的僞XML文件,所以我根據給定的規範編寫了一個解析器,所以現在我已經定義了一系列類中的所有數據,結構體。

我想要做的就是把這些數據放到JSON中,但我真的沒有看到一個好方法(我是Python的新手,這是我的第一個真正的項目) )。

我在Foo中定義了一個方法toDict(),它創建了一個字典出來的信息,但顯然不會像我希望當我嘗試序列化Bar時使用多個Foos 。

有沒有人有這樣做的好方法?過去幾天,這已經是一個非常不停的學習/代碼安排,而我對這個項目的最後一部分沒有想法。我知道關於Python的JSON模塊,但這並不能幫助我解決將數據導入字典(或類似的)的問題,而我可以將其傳遞給json.dump()。

讓我知道,如果我能以任何方式澄清。

謝謝, T.J.

回答

5

幾個意見。第一個:

  • xml.dom.minidom是一個內置的Python DOM實現。顯然,如果該文件實際上不是XML,那麼將無法使用它的內置解析函數,但它看起來像是在文件之外構建一個樹形結構,在這種情況下,您可能會使用minidom

好的,今後我會假設你有一個很好的理由來編寫自己的樹型結構,而不是使用內建函數。

  • 你確定節點應該是類嗎?這似乎是一個可怕的很多結構時,你似乎真的需要的是一堆嵌套dict S的:

    root = { 
        "foo1": { "bar1": "spam", "bar2": "ham"}, 
        "foo2": { "baz1": "spam", "baz2": "ham"}, 
    } 
    

    你的想法。

好的,也許你確定你需要單個節點是類。在這種情況下,他們都應該繼承一些BaseNode類,對吧?畢竟,它們基本上是相似的東西。

  • 在這種情況下,定義一個BaseNode.serialise方法,有效地打印有關本身的一些信息,然後對所有子調用serialise。這是一個遞歸問題;你不妨使用遞歸解決方案,除非你的樹確實是真的嵌套。

    json庫允許您繼承JSONEncoder來執行此操作。

    >>> import json 
    >>> class ComplexEncoder(json.JSONEncoder): 
    ...  def default(self, obj): 
    ...   if isinstance(obj, complex): 
    ...    return [obj.real, obj.imag] 
    ...   return json.JSONEncoder.default(self, obj) 
    ... 
    >>> dumps(2 + 1j, cls=ComplexEncoder) 
    '[2.0, 1.0]' 
    >>> ComplexEncoder().encode(2 + 1j) 
    '[2.0, 1.0]' 
    >>> list(ComplexEncoder().iterencode(2 + 1j)) 
    ['[', '2.0', ', ', '1.0', ']'] 
    
+0

沒錯。該文件原本是一種完全非結構化的格式,但在它到達我的時候,每行都被包裝在一個標籤中,並且在文件的開頭就有一個根標籤。這實際上不是XML,而是一些瘋狂的過時系統,看起來像XML。 (linebreak)這些標籤中的一部分通過它們出現的順序和其中包含的數據與其他標籤相關。我的解析器所做的就是將這些標記分解爲它們的實際結構,稱爲循環(Loops),然後我需要使用JSON等網頁友好的格式。 – tjsimmons 2010-11-03 16:16:19

+0

@tj:對不起,這是一個問題嗎? = p我不確定你在問什麼... – katrielalex 2010-11-03 21:17:56

0

無法用JSON建議任何東西,但可以使用Pickle模塊以二進制格式序列化對象。

+0

是的,問題是我需要在網絡上使用這些數據,JSON是我希望這樣做的方式。 – tjsimmons 2010-11-03 16:04:48

0

您可以考慮使用jsonpickle包---它基本上可以讓你最picklable對象轉換爲JSON。

相關問題