要解决的问题
一个对象中出现两个同名字段时,直接读成字典可能只保留后一个值。如果配置中的端口或开关被重复声明,就容易出现“文件写了一个值,程序却读到另一个值”的困惑。可以在解析时明确拒绝同对象内的重复键。
适用环境
Python 3.12,json 标准库。样本为固定字符串,不读取外部文件。
操作步骤与示例
先运行下面的小样本,再把输入替换为自己的资料;保留原始文件副本。
import json
def unique_object(pairs):
result = {}
for key, value in pairs:
if key in result:
raise ValueError("重复字段: " + key)
result[key] = value
return result
assert json.loads('{"port":8000}', object_pairs_hook=unique_object)["port"] == 8000
try:
json.loads('{"port":8000,"port":9000}', object_pairs_hook=unique_object)
except ValueError as error:
assert str(error) == "重复字段: port"
print(error)
else:
raise AssertionError("应拒绝重复字段")如何判断结果
预期报告“重复字段: port”。钩子针对每个对象分别工作,嵌套对象也会经过它;不同对象各自使用相同字段名并不属于同一对象内的重复。
常见问题与排查
语法错误仍需单独处理,不能把所有 ValueError 都向用户解释为重复键。字段名大小写不同仍是不同字符串;如果业务要求忽略大小写,应先明确规则,再实现额外校验。
适用边界
拒绝重复键不是完整的配置校验。端口范围、字段是否必填、字符串长度及访问控制还需要自己的验证逻辑。不要把“成功解析”当作可直接执行其中内容的许可。