Мой словарь имеет следующий формат:
addr_bk = {
'person': [
{'name': 'Andrew', 'id': 123, 'email': 'andrew@mailserver.com',
'phone': [{'type': 2, 'number': '633311122'},
{'type': 0, 'number': '97788665'}]
},
{'name': 'Tom', 'id': 456,
'phone': [{'type': 0, 'number': '91122334'}]},
{'name': 'Jack', 'id': 7788, 'email': 'jack@gmail.com'}
]
}
Как видно, у меня есть вложенные словари и список диктов .
Это связано с тем, что addr_bk был декодирован из данных буфера протокола, которые были преобразованы в python dict с использованием lwpb.codec. Есть необязательное поле (например, email =>, где ключ может быть недоступен) и повторяющееся поле (например, phone => преобразовано в список dict).
Я перепробовал все предложенные выше решения. Некоторые плохо обрабатывают вложенные словари. Другие не могут легко распечатать детали объекта.
Лучше всего работает только решение dict2obj (dict) от Dawie Strauss.
Я немного улучшил его, когда ключ не может быть найден:
# Work the best, with nested dictionaries & lists! :)
# Able to print out all items.
class dict2obj_new(dict):
def __init__(self, dict_):
super(dict2obj_new, self).__init__(dict_)
for key in self:
item = self[key]
if isinstance(item, list):
for idx, it in enumerate(item):
if isinstance(it, dict):
item[idx] = dict2obj_new(it)
elif isinstance(item, dict):
self[key] = dict2obj_new(item)
def __getattr__(self, key):
# Enhanced to handle key not found.
if self.has_key(key):
return self[key]
else:
return None
Затем я проверил это с помощью:
# Testing...
ab = dict2obj_new(addr_bk)
for person in ab.person:
print "Person ID:", person.id
print " Name:", person.name
# Check if optional field is available before printing.
if person.email:
print " E-mail address:", person.email
# Check if optional field is available before printing.
if person.phone:
for phone_number in person.phone:
if phone_number.type == codec.enums.PhoneType.MOBILE:
print " Mobile phone #:",
elif phone_number.type == codec.enums.PhoneType.HOME:
print " Home phone #:",
else:
print " Work phone #:",
print phone_number.number