python - 内嵌评论 ruamel.yaml

标签 python ruamel.yaml

我正在使用 ruamel.yaml 为我的个人项目的自动配置生成功能添加注释。说到这个问题,我将用一个类似的例子来使其明确。


假设您有一个默认的配置字典(自动生成):

{'auth': {'api_key': '', 'api_secret': ''}}

现在我通过以下方式将此字典加载到 CommentedMap 对象中:

yaml_config = yaml.round_trip_load(yaml.round_trip_dump(dump))

现在,我有一个元数据字典,其中包含字典中这些配置值的多行/单行描述:

{
  "auth": {
    "api_key": "Think of this as the user name that represents your account when using the app.\n# Head over to XXX.com, register an app and get your auth keys!",
    "api_secret": "Think of this as the password that represents your account when using the app.\n# Head over to XXX.com, register an app and get your auth keys!"
  }
}

我现在想要加载这些元数据项并向 yaml_config 中的相应字段添加注释。请记住,元数据转储 架构是相同的。 dumpmetadata 可以是任意数量的嵌套字典,我上面只提供了一个示例。

我尝试了以下代码来实现此功能,但它不起作用...根本没有注释或任何错误/异常。

previous_config[field_name].yaml_add_eol_comment(description, _field_name)

上述示例的正确输出应该是:

auth:
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_key: ''
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_secret: ''

最佳答案

我建议始终包含完整的工作示例 什么不能做你想做的事,因为现在还不完全清楚到底在哪里 事情出了问题。 使用 ruamel.yaml 的新开发不应使用旧 API (round_trip_load/round_trip_dump),但使用新 API(实例化 YAML()) 该 API 是几年前引入的,但您没有表明您是 使用古老的 ruamel.yaml 版本,需要使用有限的旧 API。


你想要做的事情可以通过往返结束来简单地检查是否可行 结果YAML文档,看到可以保存不变:

import sys
import ruamel.yaml

yaml_str = """\
auth:
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_key: ''
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_secret: ''
"""

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

给出:

auth:
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_key: ''
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_secret: ''

您可以检查评论属性:

print(data['auth'].ca)

打印:

Comment(comment=[None, [CommentToken('# Think of this as the password that represents your account when using the app.\n', line: 1, col: 4), CommentToken('# Head over to XXX.com, register an app and get your auth keys!\n', line: 2, col: 4)]],
  items={'api_key': [None, None, CommentToken('\n    # Think of this as the password that represents your account when using the app.\n    # Head over to XXX.com, register an app and get your auth keys!\n', line: 4, col: 4), None]})

行尾注释出现在其他数据之后,这就是名称所暗示的。在 ruamel.yaml 行尾注释通常与键相关联 一个键值对,并且这些值预计彼此位于同一行, 并且注释可以扩展到以下行,包括任何空行。为了 ruamel.yaml 和行尾注释不一定有注释 在起始行的末尾(即可以为空)。

您还应该意识到这些(内部)例程不是固定的,会改变 并且可能会停止工作,希望不会,但有时没有警告(所以修复 您安装的版本号)。

通过将以下内容关联起来,您正在给自己带来不必要的困难 注释元数据,最终必须位于键 api-key 之后 键值对 api_key: '',元数据中包含键 api-secret。 我不会解决这个 self 引发的问题。

yaml_add_eol_comment() 总是添加缺失的首字母 #,无法添​​加 多行注释,其中“真正的”行尾部分是空的, 并要求您自己缩进多行注释的行。

您还可以在上面的输出中看到有关以下内容的评论 附加的“用户名”与其他评论完全不同,因为此评论 出现在之间 键 (auth) 以及与该键关联的值(关联值是两个键 值(value))。因此,该注释需要以不同于 对 key api_key 进行评论:

import sys
import ruamel.yaml

yaml_str = """\
auth:
    api_key: ''
    api_secret: ''
"""

def indent_comment(s, indent):
    return s.replace('\n', '\n' + ' ' * indent)

MAPIND = 4

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=MAPIND)
data = yaml.load(yaml_str)
auth = data['auth']
auth.yaml_set_start_comment(
    "Think of this as the user name that represents your account when using the app.\n"
    "# Head over to XXX.com, register an app and get your auth keys!",
    indent=MAPIND,
)
auth.yaml_add_eol_comment('place_holder', 'api_key')
# correct the assigned comment token
cai = auth.ca.items['api_key'][2]
cai.value = indent_comment('\n# Think of this as the password that represents your account when using the app.\n# Head over to XXX.com, register an app and get your auth keys!', MAPIND)

yaml.dump(data, sys.stdout)

这给出了您所需的结果:

auth:
    # Think of this as the user name that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_key: ''
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_secret: ''

以上是使用ruamel.yaml==0.17.17完成的,其他版本可能需要调整。

关于python - 内嵌评论 ruamel.yaml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69866815/

相关文章:

python - firebase-python,返回 Firebase 最新更新的值?

ruamel.yaml - 如何在 ruamel.yaml 中显式写入两个引用

python - 如何为 ruamel.yaml 创建自定义 yaml 映射转储程序?

python - 为*未*通过 RoundTripLoader 加载的数据结构生成注释?

python - 在循环中捕获异常回溯,然后在脚本末尾引发错误

python - 交互链表时打印 None 而不是什么也不打印

Python - 这两行是做什么的?

python - Python 3.5 类型提示是否允许协变返回类型?

python - 如何在 Python 中向 YAML 文件添加注释