Python嵌套数据持久化

发布于 2024-11-05 17:16:20 字数 1095 浏览 0 评论 0原文

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

>>> 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 中存储腌制数据似乎很难管理。

我需要一种方法来将这些数据保存在嵌入式平台上,因此它需要依赖于纯Python和包含的模块,(或者非常容易交叉编译-我还没有尝试过,但ZODB读起来好像很容易交叉) - 编译等)

您使用过哪些灵活且直接的方法?它不需要高性能,并发性会很好,但不是“必需”,

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

I need a way to store system configuration data and i've found it easy to understand / comprehend with nested classes:

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

but this structure can't be pickled and saved. I know I could shelve it in key/value pairs:

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

but that seems like it would be hard to manage and prone to errors?

or i could save it in an sqlite DB, but then i would need a new table, and schema for each final level of config data and storing pickled data in sqlite seems like it would hard to manage.

I need a way to persist this data on an embedded platform, so it needs to relay on pure python and included modules, (or be really easy to cross compile- i haven't tried but ZODB doent read like it would be easy to cross- compile etc)

What have you used that was flexible and straight forward? It doesn't need to be high performance, and concurrency would be nice, but not 'required'

I've never had to do anything like this and was hoping you guys had some insight / experience you'd like to share!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

您的好友蓝忘机已上羡 2024-11-12 17:16:20

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

All the cool kids use json. Also, having your structure use instances instead of bare classes will make it much easier to serialize.

旧梦荧光笔 2024-11-12 17:16:20

我同意 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() 成员为键的字典递归地替换一个类,删除诸如 docmodule 之类的内容。

例如,

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

I agree with Ignacio Vazquez-Abrams that using a JSON-like structure would make it a lot easier to work with, meaning you might instead have a structure like:

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

That is, mostly dictionaries within dictionaries (and other values like strings, numbers, and lists). And then you'd need to access the elements like dictionaries, not classes, e.g,

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

instead of:

print syscnf.netwrk.iface.eth0.address

Then you can just use the json or simplejson module (or even good old pickle/cPickle) to serialize.

Of course, you do lose some prettiness, and gain a bunch of brackets. If that's important to you, then you could try something like YAML (Python module available), or you could keep what you have and hand-write a converter that recursively replaces a class with the dictionary keyed by the memebers of its dir(), removing stuff like doc and module.

E.g.,

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('__') ))

Which will then convert a class in the format you're already using into a json-like structure:

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

Then to take the serialized JSON object and make it accessible in the style you like, you could reverse the process:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文