什么是一种好的 Python 配置文件格式,可以轻松地由一个脚本编辑并由另一个脚本轻松安全地读取?
What is a good Python configuration file format that can be edited by one script easily and read by another script easily and safely?
假设我有两个 Python 脚本。一个脚本是一个 Web 界面,可以让人们编辑配置文件。另一个脚本是根据该文件中定义的配置在后台执行各种操作的脚本,它会在循环中每隔几秒重新加载一次。
这样的配置文件用什么格式比较好?我希望格式是人类可读和可编辑的,同时也易于写入和读取而不会发生冲突。
目前,我认为 json
模块可能是一个不错的选择,其中配置本质上是一个以明文形式保存到文件中的字典,并从该明文文件读取到字典中。这是一种安全的方法吗?有更好的方法吗?如果一个脚本试图从文件中读取而另一个脚本正在写入文件,是否会出现问题?应该如何解决?
所以,作为一个简单的例子,这里有两个脚本。一种是将配置写入 JSON 纯文本文件,另一种是从文件中读取配置:
作家
import random
import json
while True:
config = {"a": 1, "b": random.randint(1, 2)}
with open("config.json", "w") as file_config:
json.dump(config, file_config)
reader
import json
while True:
with open("config.json") as file_JSON:
config = json.load(file_JSON)
print(config)
当这两个脚本同时为 运行 时,reader 脚本会很快产生以下错误:
Traceback (most recent call last):
File "2_script.py", line 5, in <module>
config = json.load(file_JSON)
File "/usr/lib/python3.5/json/__init__.py", line 268, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.5/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
应该如何解决?
听起来您正在寻找两个功能:
- human-readable配置文件
- 支持一个进程写入文件而其他进程正在读取文件
我不知道这两个功能的简单解决方案,但我可以提出一些建议。
- 对适用于您的平台的文件锁定进行一些研究。这可能是获得您想要的东西的最佳选择。
- 考虑使用 SQLite 数据库而不是 human-readable 配置文件。 SQLite supports 多个读取器和一个写入器进程。您可以编写一个命令行工具来转储配置供用户查看。
- 尝试 "good enough" 尝试读取文件的解决方案,并处理读取不完整文件的任何问题。需要考虑的一些技巧是添加 "end of file" 标记或校验和以确保您没有读取不完整的文件,以及以临时名称写入文件,然后将其重命名为活动名称。失败后休眠重试。
- 在进程之间进行通信以在可以安全读取文件时通知它们,或者直接将配置数据发送到每个进程。如果 Web 服务启动后台进程,它们可以使用队列或进程池。或者,他们可以通过命名管道进行通信。
关于格式,我会考虑三种选择:
- INI 格式 - 过时的格式,但它受 built-in
configparser
模块支持
- YAML 格式 - 我更喜欢这种格式而不是 JSON,因为它支持评论
- JSON 格式 - 流行,但不支持注释:您要么必须使用像 "comment" 这样的特殊属性名称,要么在解析文件之前删除注释
假设我有两个 Python 脚本。一个脚本是一个 Web 界面,可以让人们编辑配置文件。另一个脚本是根据该文件中定义的配置在后台执行各种操作的脚本,它会在循环中每隔几秒重新加载一次。
这样的配置文件用什么格式比较好?我希望格式是人类可读和可编辑的,同时也易于写入和读取而不会发生冲突。
目前,我认为 json
模块可能是一个不错的选择,其中配置本质上是一个以明文形式保存到文件中的字典,并从该明文文件读取到字典中。这是一种安全的方法吗?有更好的方法吗?如果一个脚本试图从文件中读取而另一个脚本正在写入文件,是否会出现问题?应该如何解决?
所以,作为一个简单的例子,这里有两个脚本。一种是将配置写入 JSON 纯文本文件,另一种是从文件中读取配置:
作家
import random
import json
while True:
config = {"a": 1, "b": random.randint(1, 2)}
with open("config.json", "w") as file_config:
json.dump(config, file_config)
reader
import json
while True:
with open("config.json") as file_JSON:
config = json.load(file_JSON)
print(config)
当这两个脚本同时为 运行 时,reader 脚本会很快产生以下错误:
Traceback (most recent call last):
File "2_script.py", line 5, in <module>
config = json.load(file_JSON)
File "/usr/lib/python3.5/json/__init__.py", line 268, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.5/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
应该如何解决?
听起来您正在寻找两个功能:
- human-readable配置文件
- 支持一个进程写入文件而其他进程正在读取文件
我不知道这两个功能的简单解决方案,但我可以提出一些建议。
- 对适用于您的平台的文件锁定进行一些研究。这可能是获得您想要的东西的最佳选择。
- 考虑使用 SQLite 数据库而不是 human-readable 配置文件。 SQLite supports 多个读取器和一个写入器进程。您可以编写一个命令行工具来转储配置供用户查看。
- 尝试 "good enough" 尝试读取文件的解决方案,并处理读取不完整文件的任何问题。需要考虑的一些技巧是添加 "end of file" 标记或校验和以确保您没有读取不完整的文件,以及以临时名称写入文件,然后将其重命名为活动名称。失败后休眠重试。
- 在进程之间进行通信以在可以安全读取文件时通知它们,或者直接将配置数据发送到每个进程。如果 Web 服务启动后台进程,它们可以使用队列或进程池。或者,他们可以通过命名管道进行通信。
关于格式,我会考虑三种选择:
- INI 格式 - 过时的格式,但它受 built-in
configparser
模块支持 - YAML 格式 - 我更喜欢这种格式而不是 JSON,因为它支持评论
- JSON 格式 - 流行,但不支持注释:您要么必须使用像 "comment" 这样的特殊属性名称,要么在解析文件之前删除注释