0

我的目标是允许一种简单的方法来“过滤”先前定义的节点。考虑这个虚构的 YAML 文件:

%YAML 1.1
---
- fruit: &fruitref { type: banana, color: yellow }
- another_fruit: !rotten *fruitref

我需要在 YAML 文件或解析此文件的 Python 代码中定义什么,以便以*fruitref(即先前定义的对象,在本例中为映射)作为参数调用自定义函数并获取返回值?目标是“过滤”先前定义的值(映射、序列等)的简单而简洁的语法。

笔记

在我看来,构造!标签 *别名是无效的 YAML,因为错误:

expected <block end>, but found '<alias>'
  in "/tmp/test.yaml", line 4, column 21

这很可能意味着我将无法实现所需的语法,但我确实关心简洁性(或者更确切地说,目标用户会关心)。

采取的路线

YAML:!!python/object/apply:__main__.rotten [*fruitref]

它有效,但对于预期用途而言过于冗长;并且不需要多个参数,用例始终是别名的过滤器(先前定义的映射/序列/对象)。

YAML:%TAG !f! !!python/object/apply:__main__.

也许!f!rotten [*fruitref]可以接受,但我找不到如何使用该%TAG指令。
编辑:我发现这!!不适用于 PyYAML 3.10,它必须是这样的完整 URL:%TAG !f! %TAG !f! tag:yaml.org,2002:python/object/apply:__main__.

Python:yaml.add_constructor

我已经使用add_constructor将映射“投射”到我的类的特定实例;需要注意的是,标签别名似乎是无效的 YAML。

迄今为止最好的

add_constructor('!rotten', filter_rotten)在 Python 和!rotten [*fruitref]YAML 中似乎有效,但我想知道如果可能的话如何省略方括号。

4

1 回答 1

0

似乎不可能将标记应用于已标记的引用,因此:

!tag *reference

是不能接受的。最好的解决方案是将方括号的引用括起来(创建一个序列)并使标记成为函数调用或期望一个对象序列的特殊构造函数,因此可用的最简洁的语法是:

!prefix!suffix [*reference]

或者

!tag [*reference]
于 2014-04-28T10:05:16.977 回答