我的目标是允许一种简单的方法来“过滤”以前定义的节点。考虑这个虚构的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
这很可能意味着我无法实现所需的语法,但我确实关心简洁性(或者更确切地说,是目标用户)。
!!python/object/apply:__main__.rotten [*fruitref]
它有效,但对于预期用途而言过于冗长;并且不需要多个参数,用例始终是别名的过滤器(以前定义的映射/序列/对象)。
%TAG !f! !!python/object/apply:__main__.
也许!f!rotten [*fruitref]
可以接受,但我找不到如何使用%TAG
指令。
编辑:我发现!!
对PyYAML 3.10不起作用,它必须是这样的完整网址:%TAG !f! %TAG !f! tag:yaml.org,2002:python/object/apply:__main__.
yaml.add_constructor
我已经使用add_constructor
将“地图”转换为我的类的特定实例;需要注意的是,标签别名似乎是无效的YAML。
add_constructor('!rotten', filter_rotten)
和YAML中的!rotten [*fruitref]
似乎有效,但我想知道如果可能的话如何省略方括号。
答案 0 :(得分:0)
似乎无法将标记应用于已标记的引用,因此:
!tag *reference
是不可接受的。最好的解决方案是将引用括在方括号中(创建一个序列)并使标记成为函数调用或期望一个对象序列的特殊构造函数,因此最简洁的语法是:
!prefix!suffix [*reference]
或
!tag [*reference]