Python嵌套数据持久化

2024-10-03 15:25:14 发布

您现在位置: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
>>> 

但是这个结构不能被腌制和保存。我知道我可以把它放在键/值对中:

^{pr2}$

但这似乎很难管理,而且容易出错?在

或者我可以把它保存在sqlite数据库中,但是我需要一个新的表,并且在sqlite中存储pickled数据的每个最终级别的模式似乎很难管理。在

我需要一种在嵌入式平台上持久化这些数据的方法,因此它需要在纯python和包含的模块上进行中继(或者非常容易交叉编译——我没有尝试过,但是ZODB读起来不像交叉编译那么容易,等等)

你用了什么灵活而直截了当的方法?它不需要高性能,并发性也不错,但不是“必需的”

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


Tags: 数据方法sqliteaddresseth1route交叉class
2条回答

我同意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',
     }
  }
}

也就是说,主要是字典中的字典(以及字符串、数字和列表等其他值)。然后你需要像字典一样访问元素,而不是类,例如

^{pr2}$

而不是:

print syscnf.netwrk.iface.eth0.address

然后就可以使用json或simplejson模块(甚至是很好的老pickle/cPickle)来序列化。在

当然,你会失去一些美丽,而得到一堆括号。如果这对您很重要,那么您可以尝试类似YAML(Python module available),或者您可以保留现有的东西,手工编写一个转换器,用dir()的memebers键控的字典递归地替换类,删除诸如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

所有酷孩子都用^{}。另外,让您的结构使用实例而不是裸类将使序列化变得更容易。在

相关问题 更多 >