【问题标题】:In ruamel.yaml, how do I emit a ScalarEvent with the literal string "null"?在 ruamel.yaml 中,如何使用文字字符串“null”发出 ScalarEvent?
【发布时间】:2020-01-15 20:59:19
【问题描述】:

我正在使用 ruamel.yaml 发出一系列事件来创建自定义 YAML 文件格式混合流样式。

我发现自己无法发出值为“null”的 ScalarEvent,因此它在 YAML 文件中显示为字符串“null”,而不是 YAML 关键字 null。

以代码形式,如果我尝试

dumper = yaml.Dumper(out_file,  width=200)
param = 'field'
param_value = 'null'
dumper.emit(yaml.MappingStartEvent(anchor=None, tag=None, implicit=True, flow_style=True))
dumper.emit(yaml.ScalarEvent(anchor=None, tag=None, implicit=(True, True), value=param))
dumper.emit(yaml.ScalarEvent(anchor=None, tag=None, implicit=(True, True), value=param_value))
dumper.emit(yaml.MappingEndEvent())

我明白了

field: null

我想看看

field: 'null'

【问题讨论】:

    标签: python yaml ruamel.yaml


    【解决方案1】:

    您的代码不完整,但由于您在 映射事件,你没有得到你展示的代码,也永远不会得到你想要的输出。

    如果你想走这条路,那么看代码中唯一的地方 其中ruamel.yaml 代码发出ScalarNode。在serializer.py:

                self.emitter.emit(
                    ScalarEvent(
                        alias,
                        node.tag,
                        implicit,
                        node.value,
                        style=node.style,
                        comment=node.comment,
                    )
                )
    

    从中您选择需要添加style 范围。进一步挖掘将表明这应该是一个单一的 字符串,在您的情况下为单引号 ("'"),强制使用单引号标量。

    import sys
    import ruamel.yaml as yaml
    
    dumper = yaml.Dumper(sys.stdout,  width=200)
    param = 'field'
    param_value = 'null'
    dumper.emit(yaml.StreamStartEvent())
    dumper.emit(yaml.DocumentStartEvent())
    # !!!! changed flow_style in the next line
    dumper.emit(yaml.MappingStartEvent(anchor=None, tag=None, implicit=True, flow_style=False))
    dumper.emit(yaml.ScalarEvent(anchor=None, tag=None, implicit=(True, True), value=param))
    # added style= in next line
    dumper.emit(yaml.ScalarEvent(anchor=None, tag=None, implicit=(True, True), style="'", value=param_value))
    dumper.emit(yaml.MappingEndEvent())
    dumper.emit(yaml.DocumentEndEvent())
    dumper.emit(yaml.StreamEndEvent())
    

    给你想要的:

    field: 'null'
    

    但是,我认为你让你的生活变得比必要的更加困难。 ruamel.yaml 确实 在往返过程中保留流式,然后创建一个功能数据结构并转储它 而不是用事件来驱动翻斗车:

    import sys
    import ruamel.yaml
    
    yaml_str = """\
    a:
       - field: 'null'
         x: y
       - {field: 'null', x: y}
    """
    
    yaml = ruamel.yaml.YAML()
    data = yaml.load(yaml_str)
    for i in range(2):
        data["a"].append(ruamel.yaml.comments.CommentedMap([("a", "b"), ("c", "d")]))
    data["a"][-1].fa.set_flow_style()
    yaml.dump(data, sys.stdout)
    

    这给出了:

    a:
    - field: 'null'
      x: y
    - {field: 'null', x: y}
    - a: b
      c: d
    - {a: b, c: d}
    

    【讨论】:

    • 谢谢! ScalarEvent 'style' 参数正是我正在寻找的,我不确定我之前是怎么没有找到的。为不完整的代码道歉 - 你是正确的,我的示例不会由我提供的代码生成。不过 style 参数还是解决了我的问题。
    • 另外 - 函数式数据结构方法看起来确实比发送连续事件要简洁得多。我将不得不试一试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 2014-04-09
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多