即使yaml.explicit_end = False,yaml end(“ ...”)总是转储

时间:2019-07-09 10:19:59

标签: python yaml ruamel.yaml

我想知道这是否是错误或意图,但无论如何。

为什么转储单个值总是包含显式的YAML结尾?

import sys
from ruamel.yaml import YAML
yaml=YAML()
yaml.explicit_end=False
yaml.dump(1, sys.stdout)

生产

1
...

可以容易地跳过吗?

2 个答案:

答案 0 :(得分:1)

我不确定原因,但是var value=[ { "class": "1", "name": "Cricked" }, { "class": "2", "type": "Football" } ] db.collection_name.update({},{ $set : { "Sports": value } },{multi:true}) 不打印文档的结束标记。

似乎当序列化器获得不可迭代的值时,序列化器会附加三个点(document's end marker):

yaml.dump("1", sys.stdout)

打印:

dump(1, stream=sys.stdout)
dump([1], stream=sys.stdout)
dump(datetime.datetime.now(), stream=sys.stdout)
dump("1", stream=sys.stdout)

因此,一个简单的解决方法是将您的值转换为字符串,然后再转储它们(如果可能)...

答案 1 :(得分:1)

添加文档结束标记(...)的原因是因为 数字以 plain 标量的形式转储到 文献。如果转储字符串(假设该字符串),也会发生同样的情况 可以不加引号就转储而不会引起误解,即字符串 由数字组成的数字仅需加引号以免被看到 作为整数)。

没有文档结束标记,从流加载时,解析器 不知道文档是否完整,或者流只是在等待填充。 文档结尾标记消除了这种歧义,因此这是有意的,但例如解析文件(而不是通用流)时,也可以而且也可以通过检查文件结尾来实现。

有几种解决方法,一种是转换输出:

import sys
import ruamel.yaml

def strip_document_end_marker(s):
   if s.endswith('...\n'):
       return s[:-4]

yaml = ruamel.yaml.YAML()
yaml.dump("abc", sys.stdout, transform=strip_document_end_marker)

给出:

abc

对于多个文档,以上内容也应与dump_all一起使用(最后一个是根级普通标量)。

另一种实现此目的的方法是在写入纯值之后重置open_ended属性:

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML()

def wp(self, *args, **kw):
    self.write_plain_org(*args, **kw)
    self.open_ended = False

yaml.Emitter.write_plain_org = yaml.Emitter.write_plain
yaml.Emitter.write_plain = wp
yaml.dump("abc", sys.stdout)

这还提供:

abc