如何将函数调用应用于别名?
我的目标是让“过滤”之前定义的节点变得简单。想象一下这个虚构的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中似乎可以工作,但我在想是否有可能省略方括号。
1 个回答
0
看起来不能给已经有标签的引用再加标签,所以:
!tag *reference
这样做是不行的。最好的解决办法是把引用放在方括号里(创建一个序列),然后把标签设为一个函数调用或者一个特殊的构造器,这个构造器需要一个对象的序列。这样最简洁的写法就是:
!prefix!suffix [*reference]
或者
!tag [*reference]