首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么json文件的行为是这样的?

为什么json文件的行为是这样的?
EN

Stack Overflow用户
提问于 2022-10-06 21:15:56
回答 2查看 48关注 0票数 2

有一个函数(rui),它取数字num,并返回num的10次方。任务:编写一个装饰器,它将缓存该函数的输出,以便如果已经提交的num被输入,装饰器将输出哈希表中的值,从而不执行函数本身。如果第一次将数字输入函数(rui),那么修饰器将简单地将num和rui(num)添加到哈希表中。我将缓存数据存储在json文件中。

代码语言:javascript
复制
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文件现在是空的。执行:

代码语言:javascript
复制
rui(10)
rui(11)
rui(10)

根据这个想法,json文件现在应该是这样的:

代码语言:javascript
复制
{"10" : 10000000000, "11" : 25937424601}

但是json文件如下:

代码语言:javascript
复制
{"10": 10000000000, "11": 25937424601, "10": 10000000000}

再次执行:

代码语言:javascript
复制
rui(11)
rui(10)
rui(10)
rui(15)
rui(15)

json文件:

代码语言:javascript
复制
{"10": 10000000000, "11": 25937424601, "15": 576650390625, "15": 576650390625}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-06 21:38:02

好的,问题是:当您序列化到JSON时,键必须是字符串。但是,您的输入是int对象。我以前从未注意到这一点,但是像{'10': 'x', 10:'y'}这样的东西将被序列化为'{"10": "x", "10": "y"}'

代码语言:javascript
复制
>>> import json
>>> json.dumps({'10': 'x', 10:'y'})
'{"10": "x", "10": "y"}'

在我看来,这似乎是反常的行为,但这似乎是一个事实的结果,即Python允许任何可使用的对象作为键,但是JSON只接受字符串,而JSON实现只是天真地转换为字符串--任何存在的键。

我的建议是简单地使用另一种序列化格式,例如pickle,或者,因此围绕序列化进行一些额外的工作:

代码语言:javascript
复制
import json

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

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

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

顺便说一句,您可能需要重新考虑反序列化/序列化是否应该发生在每个修饰函数调用上,或者更确切地说,只发生一次。

票数 2
EN

Stack Overflow用户

发布于 2022-10-06 21:56:08

简单地,尝试这样做,例如,一个list/dict将int的键转换为str类型:

代码语言:javascript
复制
>>> import json
>>> obj = {"10": 10000000000, "11": 25937424601, 10: 10000000000}
>>> json.dumps(obj)
'{"10": 10000000000, "11": 25937424601, "10": 10000000000}'
>>> # oh no, YIKES!
>>> obj = {str(k): v for k: v in obj.items()}
  File "<stdin>", line 1
    obj = {str(k): v for k: v in obj.items()} 
                          ^
SyntaxError: invalid syntax
>>> obj = {str(k): v for k, v in obj.items()}
>>> json.dumps(obj)
'{"10": 10000000000, "11": 25937424601}'
>>> # oh, SNAP!

对于将被深嵌套的数据,使用递归函数将是一个很好的方法,如下所示:

代码语言:javascript
复制
import json

def dump_it_plis(o):
    return json.dumps(inner_dump_it(o))
def inner_dump_it(o):
    return {str(k): inner_dump_it(v) if isinstance(v, dict)
    else [inner_dump_it(e) for e in v] if isinstance(v, list)
    else v
     for k, v in o.items()}

obj = {"lst": [{"10": 10000000000, "11": 25937424601, 10: 10000000000}]}
print(json.dumps(obj))
# this is print:
#  {"lst": [{"10": 10000000000, "11": 25937424601, "10": 10000000000}]}
print(dump_it_plis(obj))
# this is print:
#  {"lst": [{"10": 10000000000, "11": 25937424601}]}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73980103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档