有一个函数(rui),它取数字num,并返回num的10次方。任务:编写一个装饰器,它将缓存该函数的输出,以便如果已经提交的num被输入,装饰器将输出哈希表中的值,从而不执行函数本身。如果第一次将数字输入函数(rui),那么修饰器将简单地将num和rui(num)添加到哈希表中。我将缓存数据存储在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文件:
{"10": 10000000000, "11": 25937424601, "15": 576650390625, "15": 576650390625}发布于 2022-10-06 21:38:02
好的,问题是:当您序列化到JSON时,键必须是字符串。但是,您的输入是int对象。我以前从未注意到这一点,但是像{'10': 'x', 10:'y'}这样的东西将被序列化为'{"10": "x", "10": "y"}'!
>>> import json
>>> json.dumps({'10': 'x', 10:'y'})
'{"10": "x", "10": "y"}'在我看来,这似乎是反常的行为,但这似乎是一个事实的结果,即Python允许任何可使用的对象作为键,但是JSON只接受字符串,而JSON实现只是天真地转换为字符串--任何存在的键。
我的建议是简单地使用另一种序列化格式,例如pickle,或者,因此围绕序列化进行一些额外的工作:
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顺便说一句,您可能需要重新考虑反序列化/序列化是否应该发生在每个修饰函数调用上,或者更确切地说,只发生一次。
发布于 2022-10-06 21:56:08
简单地,尝试这样做,例如,一个list/dict将int的键转换为str类型:
>>> 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!对于将被深嵌套的数据,使用递归函数将是一个很好的方法,如下所示:
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}]}https://stackoverflow.com/questions/73980103
复制相似问题