首页 > 解决方案 > 意外的 UserDict 行为

问题描述

我正在做一个项目,需要使用 UserDict 而不是 dict。我正在导入一个 JSON 文件,该文件是一个包含更多字典列表的字典。

这是一些示例代码和我看到的行为差异:

import json
from collections import UserDict
import pprint

person_string = '{"name" : "Bob", \
                  "age" : 25, \
                  "addresses":[{"city" : "Greenville", "state" : "NC" }, \
                               {"city" : "Whiteville", "state" : "NC" }]}'

# dict Example
person_dict = json.loads(person_string)
addresses = person_dict['addresses']
addr_1 = addresses[0]
print(addr_1)
print("\n")

# Add street to the first city entry
addr_1['street'] = "123 The Road"
print(addr_1)
print("\n")
pprint.pprint(person_dict)

print("\n")

# UserDict Example
person_user_dict = UserDict(json.loads(person_string))
user_addresses = person_user_dict['addresses']
user_addr_1 = UserDict(user_addresses[0])
print(user_addr_1)
print("\n")

# Add street to the first city entry
user_addr_1['street'] = "123 The Road"
print(user_addr_1)
print("\n")
pprint.pprint(person_user_dict)

输出:

# Dictionary Example
{'city': 'Greenville', 'state': 'NC'}

{'city': 'Greenville', 'state': 'NC', 'street': '123 The Road'}

{'name': 'Bob',
'age': 25,
'addresses': [{'city': 'Greenville', 'state': 'NC', 'street': '123 The Road'},
              {'city': 'Whiteville', 'state': 'NC'}]}

# UserDict Example
{'city': 'Greenville', 'state': 'NC'}

{'city': 'Greenville', 'state': 'NC', 'street': '123 The Road'}


{'name': 'Bob',
'age': 25,
'addresses': [{'city': 'Greenville', 'state': 'NC'},    <---- The 'street' is missing
               {'city': 'Whiteville', 'state': 'NC'}]}                  

为什么没有将新键添加到 person_user_dict 中,如何让 UserDict 的行为方式与字典相同?

标签: pythondictionary

解决方案


因为您在这里创建了一个新字典

user_addr_1 = UserDict(user_addresses[0])

这一点也不意外,事实上,这就是dict工作原理。如果您这样做,您会看到相同的行为:

user_addr_1 = dict(user_addresses[0])

您需要将所有字典递归地转换为UserDict对象。但实际上,您只想使用object_pairs_hookjson 解码器:

In [3]: import json
   ...: from collections import UserDict
   ...:
   ...: person_string = '{"name" : "Bob", \
   ...:                   "age" : 25, \
   ...:                   "addresses":[{"city" : "Greenville", "state" : "NC" }, \
   ...:                                {"city" : "Whiteville", "state" : "NC" }]}'

In [4]: person_dict = json.loads(person_string, object_pairs_hook=UserDict)

In [5]: person_dict
Out[5]: {'name': 'Bob', 'age': 25, 'addresses': [{'city': 'Greenville', 'state': 'NC'}, {'city': 'Whiteville', 'state': 'NC'}]}

In [6]: type(person_dict)
Out[6]: collections.UserDict

In [7]: type(person_dict['addresses'][0])
Out[7]: collections.UserDict

推荐阅读