如何将函数调用应用于别名?

时间:2014-04-12 12:39:56

标签: python yaml pyyaml

我的目标是允许一种简单的方法来“过滤”以前定义的节点。考虑这个虚构的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不起作用,它必须是这样的完整网址:%TAG !f! %TAG !f! tag:yaml.org,2002:python/object/apply:__main__.

Python:yaml.add_constructor

我已经使用add_constructor将“地图”转换为我的类的特定实例;需要注意的是,标签别名似乎是无效的YAML。

目前为止最好的

Python中的

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

1 个答案:

答案 0 :(得分:0)

似乎无法将标记应用于已标记的引用,因此:

!tag *reference

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

!prefix!suffix [*reference]

!tag [*reference]