2011-05-06 168 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