json - “刷新”不断更新的配置文件的正确方法是什么?
问题描述
我在遇到的一个问题上有点弯腰。
我有一个 python 程序,它通过 GPIO 接口(Pi 4)发送信号。信号取决于 config.json
json 的布局如下所示:
{
"key1" : val1
"key2" : val2
"key3" : val3
}
配置数据作为列表传递给调用者,并保存为设备上的 dict/json 配置文件,以便在没有新配置到达时重复使用。该程序使用以下代码来读取、编辑和保存现有或新配置:
def check_json(self, source: str, write=False, val1=940, val2=5, val3=10):
"""check_json checks whether there's an existing config on the machine and in the same folder/location
if it does exist, it gets returned to the caller. If it doesn't exist, a new file will be created
with preset data"""
if os.path.isfile(source):
if write:
try:
with open(source, "r+") as json_data: # update the existing values and save them
try:
config_data = js.load(json_data)
config_data["key1"] = val1
config_data["key2"] = val2
config_data["key3"] = val3
print(config_data)
json_data.seek(0)
json_data.truncate()
js.dump(config_data, json_data, indent=2)
json_data.flush()
except TypeError:
pass
except TypeError:
pass
else:
json_data = open(source, "r")
dict_data = js.load(json_data)
config_data = [dict_data["light_lvl"],
dict_data["on_time"], dict_data["off_time"]]
json_data.close()
return config_data
# create new with presets if json config does not exist
else:
json_data = open(source, "w")
dict_data = {"key1": val1,
"key2": on_time, "key3": val}
js.dump(dict_data, json_data, indent=2)
json_data.flush()
json_data.close()
return self.check_json(source)
一旦新配置到达,程序就会崩溃并出现以下错误:
"key1" = config_data[0]
TypeError: 'NoneType' object is not subscriptable
即使 json 的内容完好无损,也会发生错误。我尝试使用多个可见的尝试和例外,希望它会在新的迭代中继续读取新的配置数据。try 和 except 块没有一点帮助,我不知道我还能如何解决这个问题,
非常感谢任何输入、提示/技巧
解决方案
似乎我的方法不是正确的方法。我编写解决方案的方式是我可以轻松访问我的值而无需担心。但情况并非如此,因为该文件有些不稳定,从某种意义上说,它可能仍处于“接收”的过程中。
试图获取仍未完全接收的文件的值只会导致问题。有了这些,我又回到了绘图板上,稍微修改了我的概念。
类文件操作:
def __init__(self, file_name: str):
self.file_name = file_name
self.config_name = "config.json"
self.preset_config = {"key1" : val1, "key2" : val2, "key3" : val3}
def save_config(self):
"saves the newer config file and deletes it in order to avoid clutter."
if isfile(self.file_name):
with open(self.config_name, "w") as file:
js.dump(self.pass_new(), file, indent=2)
remove(self.file_name) # delete the newly arrived config to prevent clutter
def read_config(self):
"""pass the existing config over to the caller if present.
Creates a preset config using the field "preset_config" if config.json doesn't exist """
if not isfile(self.config_name):
with open(self.config_name,"w") as file:
js.dump(self.preset_config, file, indent=2)
return self.preset_config # return the preset config for now
with open(self.config_name, "r") as file:
json_string = ""
for line in file:
json_string += line
return js.loads(json_string)
def pass_new(self):
"""checks if a new config is present and passes the data through to the caller"""
if isfile(self.file_name):
with open(self.file_name, "r") as file:
json_string = ""
for line in file:
json_string += line
return js.loads(json_string)
我将文件读取操作分离到不同的文件和类,以保持一切具体和简洁,我只是对其进行了编程,以便逐行读取文件,而不是立即尝试解析它。这解决了我的问题TypeError: 'NoneType' object is not subscriptable
以及正确传递信息。
类 FIleOps 作为组合关系提供给主类,并在需要时通过简单对象调用。
推荐阅读
- gitlab - .gitlab-ci.yml 无法解析 cdcd 变量
- python-3.x - 如何从 Pandas 记录的前 N 行中获取最大值?
- node.js - 为什么我在使用 Babel 进行编译后会出现 TypeError?
- json - AWS ConfigService - 如何附加账户 ID
- php - 在将值从一个函数传递到另一个函数时,视图文件未在 codeigniter 4 中加载?
- javascript - 相同的词正在消失
- c++ - 我的 C++ 变量是在堆栈还是堆上?
- php - 使用 Laravel 和 Passport 的 401 未经身份验证的问题
- python - 如何解决:项目中未使用 Google Sheets API
- jquery - 'this' 功能需要 JQuery 帮助。列表项中的按钮