You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSON文件出现重复键问题:缓存装饰器执行异常排查

JSON缓存文件出现重复键的原因及解决方法

问题背景

现有一个计算数字10次方的函数rui,通过装饰器实现结果缓存:重复输入相同数字时直接返回JSON文件中的缓存值,首次输入则将数字与结果存入JSON文件。代码如下:

import json

def decor(func):
    def wraps(num):

        with open('inf.json') as json_file:
            dictionary = json.load(json_file)

        if num not in dictionary:
            with open('inf.json', 'w') as json_file:
                dictionary.update({num : func(num)})
                json.dump(dictionary, json_file)
        return dictionary[num]
    return wraps

@decor
def rui(num):
    return num**10

现象

初始JSON文件为空,执行以下调用:

rui(10)
rui(11)
rui(10)

预期JSON内容:

{"10" : 10000000000, "11" : 25937424601}

实际JSON内容:

{"10": 10000000000, "11": 25937424601, "10": 10000000000}

再次执行:

rui(11)
rui(10)
rui(10)
rui(15)
rui(15)

实际JSON内容出现重复的"15"键:

{"10": 10000000000, "11": 25937424601, "15": 576650390625, "15": 576650390625}

原因分析

核心问题是类型不匹配:

  • 函数rui接收的num是整数类型(比如10)
  • JSON文件的键只能是字符串类型,json.load读取后,字典的键会自动转为字符串(比如"10")
  • 判断num not in dictionary时,整数10和字符串"10"被视为完全不同的键,导致每次传入整数num都会被判定为“未缓存”,进而重复向字典中添加键值对
  • 执行json.dump时,所有非字符串类型的键会被强制转换为字符串,最终就出现了重复的字符串键

解决方法

统一键的类型:将传入的num转换为字符串后再进行缓存判断与存储,确保JSON中的键和判断用的键类型一致。修改后的代码如下:

import json

def decor(func):
    def wraps(num):
        # 将num转为字符串,统一键类型
        num_key = str(num)
        
        with open('inf.json') as json_file:
            dictionary = json.load(json_file)

        if num_key not in dictionary:
            result = func(num)
            dictionary[num_key] = result
            with open('inf.json', 'w') as json_file:
                json.dump(dictionary, json_file)
        return dictionary[num_key]
    return wraps

@decor
def rui(num):
    return num**10

验证效果

执行相同调用后,JSON文件会正确存储唯一的键值对,不会再出现重复键。


内容的提问来源于stack exchange,提问作者xSAMx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:55:21