【问题标题】: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 配置文件格式是什么?
【发布时间】:2018-07-21 22:56:15
【问题描述】:

假设我有两个 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)

阅读器

import json

while True:
    with open("config.json") as file_JSON:
        config = json.load(file_JSON)
    print(config)

当这两个脚本同时运行时,阅读器脚本会很快产生以下错误:

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)

应该如何解决?

【问题讨论】:

  • json 或 yaml...
  • @StephenRauch 谢谢。如前所述,这些如何应对一个脚本写入它们的同时另一个脚本从它们读取的情况?
  • 它们只是文件。使用文件锁。
  • @StephenRauch 是否有一些标准库解决方案?我看到很多针对它的自制代码,但我想要一些简单、Pythonic 和安全的代码。
  • 锁定是一个大而重要的问题。非常依赖环境。我不相信你会找到一个简单的现成答案。这些是数据库解决的一些问题。

标签: python json configuration semaphore


【解决方案1】:

听起来您正在寻找两个功能:

  1. 人类可读的配置文件
  2. 支持一个进程在其他进程读取文件时写入文件

我不知道这两个功能的简单解决方案,但我可以提出一些建议。

  1. 对您的平台的文件锁定进行一些研究。这可能是获得您想要的东西的最佳选择。
  2. 考虑使用 SQLite 数据库而不是人类可读的配置文件。 SQLite supports 多个读取器和单个写入器进程。您可以编写一个命令行工具来转储配置供用户查看。
  3. 尝试“足够好”的解决方案,尝试读取文件,并处理读取不完整文件时出现的任何问题。要考虑的一些技巧是添加“文件结束”标记或校验和以确保您没有读取不完整的文件,以及以临时名称写入文件,然后将其重命名为活动名称。失败后,休眠并重试。
  4. 在进程之间进行通信以在可以安全读取文件时通知它们,或者直接将配置数据发送到每个进程。如果 Web 服务启动后台进程,它们可以使用队列或进程池。或者,它们可以通过命名管道进行通信。

至于格式,我会考虑三个选项:

  1. INI 格式 - 老式,但内置 configparser 模块支持它
  2. YAML 格式 - 我更喜欢这个而不是 JSON,因为它支持 cmets
  3. JSON 格式 - 流行,但不支持 cmets:您要么必须使用特殊属性名称,如“comment”,要么在解析文件之前去掉 cmets

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 2018-11-24
    相关资源
    最近更新 更多