Python嵌套数据持久性

时间:2011-05-06 02:37:43

标签: python data-structures persistence

我需要一种存储系统配置数据的方法,我发现使用嵌套类很容易理解/理解:

>>> 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就像读取它一样易于交叉编译等)

你使用了哪些是灵活而直接的?它不需要高性能,并发性很好,但不是“必需”

我从来没有做过这样的事情,希望你们有一些你想分享的见解/经验!

2 个答案:

答案 0 :(得分:4)

所有酷孩子都使用json。此外,让您的结构使用实例而不是裸类将使序列化更容易。

答案 1 :(得分:3)

我同意Ignacio Vazquez-Abrams的观点,即使用类似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

E.g:

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