python - 意外的 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 的行为方式与字典相同?
解决方案
因为您在这里创建了一个新字典:
user_addr_1 = UserDict(user_addresses[0])
这一点也不意外,事实上,这就是dict
工作原理。如果您这样做,您会看到相同的行为:
user_addr_1 = dict(user_addresses[0])
您需要将所有字典递归地转换为UserDict
对象。但实际上,您只想使用object_pairs_hook
json 解码器:
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
推荐阅读
- javascript - TypeError: ctx.onCreditChange 不是函数角度
- java - 正则表达式允许数字之间有空格或在第一个之前没有空格
- javascript - 将自定义字符串转换为 Angular 日期
- grails - Grails 3.3.11 集成测试 - 回滚事务
- jquery - 引导程序 | JQuery:如何在表单提交单击期间对字段启用“必需”验证?
- vba - SAP GUI 脚本记录仅捕获部分动作
- java - 为什么我的 Jsoup 代码没有返回正确的元素?
- javascript - 动态引导模式,jQuery 在首次加载时无法访问 html 元素
- html - 如何在 Angular 中启用单击项目
- r - 使用唯一标识符,将行值与 R 中的列名匹配