Struct-like в python

78
7

Используя Python, я пытаюсь написать объект, доступ к которому будет таким:

page[2].records[7].color = "ffff"

(в "записи" есть несколько полей).

объект должен быть экспортирован в строку json и, конечно, импортирован из json (в настоящее время не завершен), поэтому я добавил метод toString().

Дело в том, что код очень "неуклюжий". Есть ли способ (с помощью python) сделать более "красивый" код?

мой код:

class Record ():
'''
'''
def __init__(self, title, color, action, data) :
self.title = title
self.color = color
self.action = action
self.data = data
def toDict(self) :
ans = {'title':self.title, 'color':self.color, 'action':self.action, 'data':self.data}
return ans
def toString(self):
return '%s' % self.toDict()
#-----------------------------------------------------------------------
class Records():
'''
'''
def __init__(self):
self.f_record = {}
def __getitem__(self, key):
if not(self.f_record.get(key,None)):
self.f_record[key] = Record(None,None,None,None)
return self.f_record[key]
def __setitem__(self, key, value):
self.f_record[key] = value
def toDict(self):
ans = {}
for i in self.f_record:
ans[i] = self.f_record[i].toString()
return ans
def toString(self):
return '%s' % self.toDict()
#-----------------------------------------------------------------------
class Page():
'''
'''
def __init__(self):
self.records = Records()
def toString(self):
return self.records.toString()
#-----------------------------------------------------------------------
class Papers():
'''
'''
def __init__(self):
self.f_papers = {}
def __getitem__(self,key):
if not (self.f_papers.get(key,None)):
self.f_papers[key] = Page()
return self.f_papers[key]
def toString(self):
ans = {}
for i in self.f_papers:
ans[i] = self.f_papers[i].toString()
return '%s' % ans
#-----------------------------------------------------------------------
#tests

a = Papers()
a[1].records[1] = Record('group','red','open', 'group1')
a[1].records[2] = Record('group','green','open', 'group2')

a[2].records[7].title = "ffff"
a[1].records[1].title = 'title :-) '

print a[1].records[1].toString()
print a.toString()

спросил(а) 2021-01-19T16:43:47+03:00 6 месяцев, 1 неделя назад
1
Решение
64

Чтобы сериализовать свой объект на json:

import json

json_text = json.dumps(your_obj.as_dict())

Чтобы создать свой объект из json:

obj = YourClass.from_dict(json.loads(json_text))

Вы можете легко реализовать методы:

class YourClass(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
@classmethod
def from_dict(cls, attrs):
return cls(**attrs)
def as_dict(self):
return dict(self.__dict__)
def __str__(self):
return json.dumps(self.as_dict())
def __repr__(self):
# see http://docs.python.org/3/library/types.html#types.SimpleNamespace
d = self.as_dict()
items = ("{}={!r}".format(k, d[k]) for k in sorted(d))
return "{}({})".format(type(self).__name__, ", ".join(items))

Пример:

>>> obj = YourClass(title="foo", name="bar")
>>> obj.color = "ffffff"
>>> obj.name
'bar'
>>> obj
YourClass(color='ffffff', name='bar', title='foo')
>>> print(obj)
{"name": "bar", "color": "ffffff", "title": "foo"}
>>> obj.as_dict()
{'name': 'bar', 'color': 'ffffff', 'title': 'foo'}

Вы можете определить from_json, as_json методы, если вы хотите использовать однострочные

ответил(а) 2021-01-19T16:43:47+03:00 6 месяцев, 1 неделя назад
63

Вы можете использовать dict непосредственно, чтобы сделать его немного легче:

from collections import defaultdict

class PropertyDict (dict):
def __getattr__ (self, attr):
if self.has_key(attr):
return self.__getitem__(attr)
return object.__getattr(self, attr)

def __setattr__ (self, attr, value):
self.__setitem__(attr, value)

class Record (PropertyDict):
def __init__ (self, title = None, color = None, action = None, data = None):
self.title = title
self.color = color
self.action = action
self.data = data

class Page (PropertyDict):
def __init__ (self):
self.records = defaultdict(Record)

papers = defaultdict(Page)
papers[1].records[1] = Record('group', 'red', 'open', 'group1')
papers[1].records[2] = Record('group', 'green', 'open', 'group2')

papers[2].records[7].title = "ffff"
papers[1].records[1].title = 'title :-) '

print(papers[1].records[1])
print(papers)

Поскольку объекты теперь являются подтипами dict, сериализация его с помощью json проста. Только для десериализации вы должны будете написать свой собственный обработчик кодировки.

ответил(а) 2021-01-19T16:43:47+03:00 6 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема