Simplejson dump и load не возвращают правильный словарь - PullRequest
2 голосов
/ 03 января 2011

Я пытаюсь сохранить результат json в хранилище данных GAE, чтобы прочитать его позже.Я сбрасываю его в строку, затем сохраняю, затем читаю и загружаю обратно в диктовку.Но я больше не могу читать его как диктат после загрузки.

result = freebase.mqlready(query)

Результат печати:

[{u'mid': u'/m/095hd',
  u'name': u'Settlers of Catan',
  u'type': u'/games/game'},
 {u'mid': u'/m/025sm93',
  u'name': u'The Game of Life',
  u'type': u'/games/game'}]

for r in result:
    name = r.name # works, I can get the name and other values.

json_dump = simplejson.dumps(result)
text = db.Text(json_dump)
fbresult = model.FB(text=text)
fbresult.put()
####
stored_text = fbresult.text
json = simplejson.loads(stored_text)

Печать json:

[{u'mid': u'/m/095hd',
  u'name': u'Settlers of Catan',
  u'type': u'/games/game'},
 {u'mid': u'/m/025sm93',
  u'name': u'The Game of Life',
  u'type': u'/games/game'}]

for j in json:
    name = json.name 

ОШИБКА:

AttributeError: 'dict' object has no attribute 'name'

Ответы [ 3 ]

9 голосов
/ 03 января 2011

Э-э, похоже, вы обращаетесь к коллекции, а не к внутреннему объекту:

Конечно, вы имели в виду:

for j in json:
    name = j['name']
2 голосов
/ 03 января 2011

Обычный словарь не преобразует доступ к атрибутам в поиск элементов:

>>> d = {'name': 'Joe'}
>>> d.name
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'name'
>>> d['name']
'Joe'

simplejson возвращает стандартные словари по умолчанию.

Вы можете использовать Storage объект, похожий на словарь, за исключением того, что obj.foo может использоваться в дополнение к obj['foo'].

>>> from storage import Storage
>>> s = Storage(d)
>>> s['name']
'Joe'
>>> s.name
'Joe'

Вы можете преобразовать все json-объекты в Storage, используя object_hook параметр:

obj = simplejson.loads(stored_text, object_hook=Storage)
1 голос
/ 03 января 2011

Кажется, что result, возвращаемый freebase.mqlready, не является реальным диктатом, а подклассом, который делегирует __getitem__ через __getattr__ (то есть: вы можете сделать r.name вместо r['name']).simplejson может просто сбросить его (это подкласс dict), но когда он загружает его обратно, он возвращает простой dict, который не делегирует доступ к атрибуту для доступа к элементу.

...