要解决的问题

一个对象中出现两个同名字段时,直接读成字典可能只保留后一个值。如果配置中的端口或开关被重复声明,就容易出现“文件写了一个值,程序却读到另一个值”的困惑。可以在解析时明确拒绝同对象内的重复键。

适用环境

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 都向用户解释为重复键。字段名大小写不同仍是不同字符串;如果业务要求忽略大小写,应先明确规则,再实现额外校验。

适用边界

拒绝重复键不是完整的配置校验。端口范围、字段是否必填、字符串长度及访问控制还需要自己的验证逻辑。不要把“成功解析”当作可直接执行其中内容的许可。

参考资料