2011-05-06 307 views
1

嵌套的數據,我需要一種方法來存儲系統配置數據和我發現它很容易理解/嵌套類領悟:Python的持久性

>>> class syscnf: 
...  class netwrk: 
...   class iface: 
...    class eth0: 
...     address = '192.168.0.100' 
...     netmask = '255.255.255.0' 
...     mtu = 1500 
...    class eth1: 
...     address = '172.25.0.23' 
...     netmask = '255.255.255.128' 
...   class route: 
...    default = '192.168.0.1' 
>>> 
>>> print syscnf.netwrk.iface.eth0.address 
192.168.0.100 
>>> 

但這種結構不能被醃製和保存。我知道我可以在鍵/值對擱置:

syscnf.netwrk.iface.eth0.address => 192.168.0.100 
syscnf.netwrk.iface.eth0.netmask => 255.255.255.0 
syscnf.netwrk.route.default => 192.168.0.1 
syscnf.... etc 

但是,似乎這將是難以管理和容易出錯?

或者我可以將它保存在一個sqlite數據庫中,但然後我需要一個新表,並且每個最終配置數據級別的模式和在sqlite中存儲pickle數據看起來好像很難管理。我需要一種方法來將這些數據保存在嵌入式平臺上,因此它需要在純Python和包含的模塊上進行中繼(或者很容易進行交叉編譯 - 我沒有嘗試過,但是ZODB doent像它那樣讀取很容易交叉編譯等)

你用什麼,這是靈活和直截了當?它並不需要高性能,併發性會很好,但不是'必需'

我從來沒有做過這樣的事情,希望你們有一些洞察/經驗,你想分享!

+3

爲什麼這不僅僅是一本字典? – 2011-05-06 02:58:23

回答

3

我伊格納西奧巴斯克斯 - 艾布拉姆斯同意在使用JSON狀結構將使人們更方便地工作着,這意味着你可能反而有這樣的結構:

syscnf = { 
    'netwrk': { 
    'iface': { 
     'eth0': { 
      'address': '192.168.0.100', 
      'netmask': '255.255.255.0', 
      'mtu': 1500, 
     } 
     # ... 
    } 
    'route': { 
     'default': '192.168.0.1', 
    } 
    } 
} 

也就是說,內大多字典字典(以及字符串,數字和列表等其他值)。然後,你需要訪問像字典,而不是類,如元素,

print syscnf['netwrk']['iface']['eth0']['address'] 

代替:

print syscnf.netwrk.iface.eth0.address 

然後,你可以使用JSON或simplejson模塊(甚至好老pickle/cPickle)序列化。

當然,你確實失去了一些可愛,並獲得了一堆括號。如果這對你很重要,那麼你可以嘗試類似YAML(可用的Python模塊),或者你可以保留你擁有的東西,並手動編寫一個轉換器,遞歸地用dir()的成員鍵入的字典遞歸地替換一個類,刪除諸如doc模塊

例如,

from types import ClassType 
def jsonize_class(klass): 
    def recurse(child): 
    return jsonize_class(child) if isinstance(child, ClassType) else child 
    def entry(key): 
    return key, recurse(getattr(klass,key)) 
    return dict((entry(key) for key in dir(klass) if not key.startswith('__'))) 

然後將轉換成你已經在使用成JSON狀結構格式的類:

>>> class bob: 
...  x = 9 
...  y = "hello" 
...  class job: 
...    bill = 999 
...  class rob: 
...    pass 
... 
>>> jsonize_class(bob) 
{'y': 'hello', 'x': 9, 'job': {'bill': 999}, 'rob': {}} 

然後把序列化JSON對象,並使其在風格訪問你喜歡,你可以扭轉這一進程:

from types import DictType 
def classize_json(the_json): 
    if isinstance(the_json, DictType): 
    class returned_class: pass 
    for key, val in the_json.iteritems(): 
     setattr(returned_class, key, classize_json(val)) 
    return returned_class 
    else: 
    return the_json 

如:

>>> jBob = jsonize_class(bob) 
>>> jBob 
{'y': 'hello', 'x': 9, 'job': {'bill': 999}, 'jimmy': 99, 'rob': {}} 
>>> cBob = classize_json(jBob) 
>>> cBob.y 
'hello' 
>>> cBob.job.bill 
999 
>>> cBob.jimmy 
99 
+1

順便說一句,我玩的有點快和鬆散的術語「JSON」經常用它來表示任何*可以*是JSON編碼的 - 不要讓它拋出你 – 2011-05-07 02:56:20

4

所有酷酷的孩子使用json。另外,讓你的結構使用實例而不是裸類將使序列化變得更容易。

+0

是否對序列化字典中的json有利? – tMC 2011-05-06 03:23:25

+0

JSON是序列化字典的一種可能方法。 – 2011-05-06 03:30:33