Персистентность вложенных данных Python

1

Мне нужен способ хранения данных конфигурации системы, и я нашел его легким для понимания/понимания с помощью вложенных классов:

>>> 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 DB, но тогда мне понадобится новая таблица, а схема для каждого конечного уровня данных конфигурации и хранения маринованных данных в sqlite кажется, что это будет сложно управлять.

Мне нужен способ сохранить эти данные на встроенной платформе, поэтому ему нужно передать на чистые python и включенные модули (или быть очень легко перекрестно компилировать - я не пробовал, но код ZODB читал, как будто бы это было бы легко скомпилировать и т.д.)

Что вы использовали, что было гибким и прямым? Это не должно быть высокой производительности, и concurrency будет приятным, но не "обязательным"

Мне никогда не приходилось делать что-либо подобное, и надеялся, что у вас, ребята, есть понимание/опыт, который вы хотели бы поделиться!

  • 3
    Почему это не просто словарь?
Теги:
data-structures
persistence

2 ответа

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), или вы можете сохранить то, что у вас есть, напишите конвертер, который рекурсивно заменяет класс словарем, связанным с memebers его 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 - не позволяйте этому бросить вас
4

Все классные дети используют json. Кроме того, если ваша структура использует экземпляры вместо простых классов, это значительно упростит сериализацию.

  • 0
    есть ли преимущество для JSON над сериализованным словарем?
  • 0
    JSON - это один из возможных методов сериализации словаря.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню