Pracuję z zagnieżdżonymi strukturami danych podobnymi do JSON w python 2.7, które wymieniam z obcym kodem perl. Po prostu chcę "pracować" z tymi zagnieżdżonymi strukturami list i słowników w sposób amoronowy.Używanie kluczy JSON jako atrybutów w zagnieżdżonych JSON
Więc jeśli mam strukturę tak ...
a = {
'x': 4,
'y': [2, 3, { 'a': 55, 'b': 66 }],
}
... Chcę być w stanie poradzić sobie z nim w skrypcie Pythona jakby był zagnieżdżone klas Python/elemencie, tak :
>>> aa = j2p(a) # <<- this is what I'm after.
>>> print aa.x
4
>>> aa.z = 99
>>> print a
{
'x': 4,
'y': [2, 3, { 'a': 55, 'b': 66 }],
'z': 99
}
>>> aa.y[2].b = 999
>>> print a
{
'x': 4,
'y': [2, 3, { 'a': 55, 'b': 999 }],
'z': 99
}
Tak więc aa jest pełnomocnikiem w pierwotnej strukturze. Oto, do czego do tej pory doszedłem, zainspirowane doskonałym pytaniem o numer What is a metaclass in Python?.
def j2p(x):
"""j2p creates a pythonic interface to nested arrays and
dictionaries, as returned by json readers.
>>> a = { 'x':[5,8], 'y':5}
>>> aa = j2p(a)
>>> aa.y=7
>>> print a
{'x': [5, 8], 'y':7}
>>> aa.x[1]=99
>>> print a
{'x': [5, 99], 'y':7}
>>> aa.x[0] = {'g':5, 'h':9}
>>> print a
{'x': [ {'g':5, 'h':9} , 99], 'y':7}
>>> print aa.x[0].g
5
"""
if isinstance(x, list):
return _list_proxy(x)
elif isinstance(x, dict):
return _dict_proxy(x)
else:
return x
class _list_proxy(object):
def __init__(self, proxied_list):
object.__setattr__(self, 'data', proxied_list)
def __getitem__(self, a):
return j2p(object.__getattribute__(self, 'data').__getitem__(a))
def __setitem__(self, a, v):
return object.__getattribute__(self, 'data').__setitem__(a, v)
class _dict_proxy(_list_proxy):
def __init__(self, proxied_dict):
_list_proxy.__init__(self, proxied_dict)
def __getattribute__(self, a):
return j2p(object.__getattribute__(self, 'data').__getitem__(a))
def __setattr__(self, a, v):
return object.__getattribute__(self, 'data').__setitem__(a, v)
def p2j(x):
"""p2j gives back the underlying json-ic json-ic nested
dictionary/list structure of an object or attribute created with
j2p.
"""
if isinstance(x, (_list_proxy, _dict_proxy)):
return object.__getattribute__(x, 'data')
else:
return x
Teraz zastanawiam się, czy istnieje elegancki sposób mapowania cały zestaw z __*__
funkcji specjalnych, jak __iter__
, __delitem__
? więc nie trzeba rozpakowywać rzeczy przy użyciu p2j()
tylko po to, aby powtarzać lub wykonywać inne pythonicowe rzeczy.
# today:
for i in p2j(aa.y):
print i
# would like to...
for i in aa.y:
print i
myślę szukasz to rozwiązanie - http://stackoverflow.com/questions/4984647/accessing-dict-keys-like-an-attribute-in-python#answer-14620633 – Yurik