python - 这是一个有效的 YAML 文件吗?
问题描述
考虑以下文件:
- k0: v0
vars: &splat0
VAR0: potato # vars from blob0
- k1: v1
vars: &splat1
VAR1: spud # vars from blob1
- k: v
extra: # merged vars from blob0 + blob1
<<: *splat0
<<: *splat1
它利用了 YAML 的合并键特性。
这是一个有效的 YAML 文件吗?规范 ( 1.1 , 1.2 ) 说在映射节点中存在“每个键都是唯一的限制”,但是不清楚合并键本身是否受到唯一性约束,或者是否只有映射键之后已解决的合并必须是唯一的。
PyYAML 解析并合并键,但注释丢失。ruamel 能够保留注释但会引发 a DuplicateKeyError
,如果您明确允许重复键,那么它会解析但合并会丢失。
这个输入是有效的 YAML 吗?它应该如何在 Python 中正确解析?
解决方案
合并键就像任何其他键一样,它们仅在YAML 解析器实现合并键扩展时以特殊定义的方式进行解释(这不是必须的)。在我看来,这是无效的 YAML。
但是,即使合并键非常特殊以至于它不遵循正常的键限制,也有另一个反对这一点的论点。假设您的输入文件如下所示:
- k0: v0
vars: &splat0
VAR0: potato # vars from blob0
VAR2: tater
- k1: v1
vars: &splat1
VAR1: spud # vars from blob1
VAR2: tuber
- k: v
extra: # merged vars from blob0 + blob1
<<: *splat0
<<: *splat1
并且还假设您可以将这个不正确的 YAML 加载到data
. 的价值是 data[2]['extra']['VAR2']
多少?
由于 YAML 规范明确指出:
特别是,在合成过程中不应引用映射键顺序、注释和标签句柄。
因此,除非您打破另一个明确的限制(密钥排序),否则您无法正确解析它(这就是 PyYAML 所做的。恕我直言,一个错误)。
这意味着当您正确实现 YAML 规范时,您无法决定是先用 a还是用data[2]['extra']
更新的值。这就是为什么不允许这样做。VAR2: tuber
VAR2: tater
ruamel.yaml
当然,在合并密钥规范中明确定义了VAR2
您在执行此操作时获得的密钥值:
<<: [*splat0, *splat1]
推荐阅读
- branch - Branch.io sharesheet 不起作用,没有任何错误或错误
- bash - 为什么 bash 忽略了 ls 输出中的引号?
- python - 使用带有 ci 参数的 seaborn 线图时获取波段值
- reactjs - 重置 recaptcha 时出现问题 - 无法读取代码的 null 属性“重置”
- docker - Travis 条件构建 - 如何跳过除主分支之外的部署阶段
- java - 使用 charAt() 时无法打印字符串
- mysql - GoLang 的配置返回“非名称”错误
- cvxpy - 尝试为正半定锥约束创建约束时,问题不遵循 DCP 规则
- java - 为多个主类创建 1 个 jar 文件
- python-3.x - 为什么“全局”在“如果”中不起作用?