使用 python 在 .json 文件中存储数据的所有不同方法是啥?

Posted

技术标签:

【中文标题】使用 python 在 .json 文件中存储数据的所有不同方法是啥?【英文标题】:What are all the different ways of storing data in a .json file using python?使用 python 在 .json 文件中存储数据的所有不同方法是什么? 【发布时间】:2021-05-11 15:35:06 【问题描述】:

我目前一直在为我的 discord.py 机器人开发警告系统。我一直做得很好,直到我意识到我不知道如何添加到文件而不是覆盖文件。我不想添加到文件的末尾,因为我希望它按不和谐公会分类,然后是公会成员。因此,当有人想要检查他们的警告时,它只会在调用该命令的特定行会中显示他们的警告。我的问题是将信息存储到 .json 文件的所有不同方式是什么?

例如:warn_list[str(ctx.guild.id)][member.id].add(stuff in here)

如示例中所示,我不想知道存储又名'a''w' 等的不同模式。我想知道,如果有的话,可以在最后添加什么。喜欢.append().add()。我在 google 上查找了一个列表,但找不到我要查找的信息。任何帮助将不胜感激。

真诚地, 杀羚羊

【问题讨论】:

JSON 文件只是文本,JSON 只是基于文本的序列化格式。通常,您在 Python 中操作一些反序列化的数据结构,再次序列化整个事物并覆盖整个文件。您甚至可以操作表示 JSON 的字符串,但通常要避免这种情况。如果这种东西无法扩展,那么您正在寻找某种数据库,而不仅仅是 JSON 文件。 告诉我warn_list[str(ctx.guild.id)][member.id] 是什么对象,我会告诉你它支持什么功能。我无法在网上找到任何关于定制warn_list 的信息,所以我猜你自己创建了这个结构。如果你有地方可以捕获终端输出(比如一个日志文件),那么你总是可以print(dir(warn_list[str(ctx.guild.id)][member.id])),它会列出它支持的功能。 @RazzleShazl warn_list 当前为json.load,代码行为warn_list = json.load(f)。它的作用是在有人收到警告时将信息放入.json 文件中,但我希望它不会覆盖预先存在的数据,而只是添加到预先存在的数据中。 warn_list = json.load(f) 会将您保存的文件的内容反序列化为 python 对象。这是读取步骤。我猜在你的代码的某个地方,有一个反向事务,你的内存对象被序列化到保存的文件中。你能找到并分享那行代码吗? @RazzleShazl 是的,with open('warnings.json', 'w') as f: json.dump(warn_list, f) 【参考方案1】:

如何添加持久化到 JSON 的自定义数据

您正在向字典添加数据,因此您将使用 dict[key] = value 添加数据,并使用 value = dict[key] 读取数据 1 。要添加到 list 的末尾,请使用 append()

你已经很接近你所拥有的了。让我们重构一下思路清晰:

warns_for_a_user = warn_list[str(ctx.guild.id)][member.id]

我们可以直接使用这个字典来存储关于这个member.id的警告信息。我们需要一个数据结构,我认为list 符合要求(或dict)。您可能需要这些警告中的时间信息,而时间似乎是一个合理的排序顺序和/或主键。

我想知道,如果有的话,最后可以加什么

通常不会直接修改.json 文件。修改.json 文件的唯一可靠方法是将整个内容导入内存,然后在修改后将其保存回.json

.json 文件视为照片 或及时快照。如果场景发生了变化,您只需扔掉旧照片并拍摄另一张照片;如果状态已更新,我们只需将旧的warnings.json 丢弃并创建一个新的warnings.json

第 1 步:添加新字段并追加到新字段

鉴于我们有最新的warning 的信息,我们可以将其保存到用户的历史记录中:

# working with givens:
warning =  "type": "spam", "count": "20", "timestamp": 1612756912.987963 

if not history in warns_for_a_user:
    warns_for_a_user['history'] = []
warns_for_a_user['history'].append([warning['timestamp'], warning])

您添加的这些新字段不应与任何内容冲突,因为它们是其他代码部分未知的定制字段。

如果您发现将每个警告包装在时间戳中很复杂,那是因为确实如此。但是,通常选择单个字段(或字段组合)作为整个对象的代表键。这有助于人类直接读取json文件,也可以简化处理逻辑。

第 2 步:读取新字段数据

稍后,用户想要查看他的警告。以下内容一次打印一个警告(日期时间代码来自SO):

import datetime
for epoch_time, warn in warns_for_a_user['history']:
    _datetime = datetime.datetime.fromtimestamp(epoch_time)
    _human_datetime = _datetime.strftime('%Y-%m-%d %H:%M:%S')
    print(f"_human_datetime: [warn['count']x] warn['type']")

输出:

2021-02-07 20:01:52: [20x] spam

支持的数据类型

JSON 编码器文档有一个mapping 说明它如何将序列化的 JSON 数据转换为反序列化的 Python 对象。请注意,它将元组转换为列表。

检查warnings.json

如果您按照我的示例进行操作,您应该会在 warnings.json 的相应用户下看到以下添加:

"history": [[1612756912.987963, "count": 20, "type": "spam", "timestamp": 1612756912.987963]]

1 方括号表示法是__getitem__()__setitem__() 的语法糖

【讨论】:

好的,感谢您的精彩深入解释。我见过有人用这种方法来计数。我假设你只能这样做,因为否则它会覆盖,最好知道哪个警告。很抱歉没有尽快回复,因为我没有在我的电脑上,祝你有美好的一天! @killrebeest 我假设你只能这样做,因为否则它会覆盖,最好知道哪个警告 - 抱歉,我不太关注这个,这是我的问题吗?

以上是关于使用 python 在 .json 文件中存储数据的所有不同方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何将json中的数据存储在sql表中(python)

Python学习——使用json模块存储数据

在 KivyMD Python 中将数据存储在 JSON 文件中时出错

将数据存储在 JSON 文件中时出现类型错误。(KivyMD Python)

python - 如何在python中附加一个列表时处理异常,其中包含从存储从.json文件读取的数据的dict读取的数据?

Python学习文件操作和异常处理以及使用json存储数据