我试图理解https://pyyaml.org/wiki/PyYAML上的说法:
PyYAML features
- a complete YAML 1.1 parser. In particular, PyYAML can parse all
examples from the specification. 如果您转到使用PyYAML (http://yaml-online-parser.appspot.com/)的在线YAML解析器,那么从规范获取的几个示例不工作。
我知道您需要为其中一些故障定义标记,而且在线解析器只能处理单个文档YAML,我知道如何在使用PyYAML时“修复”这个问题。
但是示例11也失败了,它没有特殊的标记,而且是一个单一的文档。PyYAML怎么能声称它可以解析所有的例子,而它显然没有?这是因为PyYAML适用于YAML 1.1,并且示例来自YAML 1.2规范吗?
发布于 2019-01-01 13:34:14
首先是最后一个问题:这是,而不是,因为后面的规范提供了示例。假设您仅局限于规范中的预览章节/部分(在线解析器也是如此),并考虑到我只是在视觉上比较了示例(即不基于字符),那么1.2和1.1章节/第2节规范中的示例是相同的。
您的误解来自在线解析器标题中使用的解析器一词。它实际上要做的是加载YAML,然后转储到JSON、Python或规范的YAML。PyYAML中的加载由YAML规范中的Processing Overview图片中提到的各个阶段( 1.1和1.2相同)组成,从基于字符的文档开始:解析、合成和构造步骤。
PyYAML在解析步骤上没有失败,它在构造步骤上失败,因为( @torek表示) PyYAML构造了一个list,并且不能用作dict的键。这是对Python的dict实现的限制,也是PyYAML的缺陷之一。
import sys
import yaml as pyyaml
yaml_1_1_example_2_11 = """\
? - Detroit Tigers
- Chicago cubs
:
- 2001-07-23
? [ New York Yankees,
Atlanta Braves ]
: [ 2001-07-02, 2001-08-12,
2001-08-14 ]
"""
for event in pyyaml.parse(yaml_1_1_example_2_11):
print(event)给予:
StreamStartEvent()
DocumentStartEvent()
MappingStartEvent(anchor=None, tag=None, implicit=True)
SequenceStartEvent(anchor=None, tag=None, implicit=True)
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value='Detroit Tigers')
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value='Chicago cubs')
SequenceEndEvent()
SequenceStartEvent(anchor=None, tag=None, implicit=True)
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value='2001-07-23')
SequenceEndEvent()
SequenceStartEvent(anchor=None, tag=None, implicit=True)
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value='New York Yankees')
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value='Atlanta Braves')
SequenceEndEvent()
SequenceStartEvent(anchor=None, tag=None, implicit=True)
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value='2001-07-02')
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value='2001-08-12')
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value='2001-08-14')
SequenceEndEvent()
MappingEndEvent()
DocumentEndEvent()
StreamEndEvent()因此,PyYAML 可以正确地解析。不仅如此,如果联机“解析器”在发出规范的YAML时不尝试加载、然后转储,它还可以处理这个示例(替换上面代码的最后两行):
pyyaml.emit(pyyaml.parse(yaml_1_1_example_2_11), stream=sys.stdout, canonical=True)因为这意味着:
---
{
? [
! "Detroit Tigers",
! "Chicago cubs",
]
: [
! "2001-07-23",
],
? [
! "New York Yankees",
! "Atlanta Braves",
]
: [
! "2001-07-02",
! "2001-08-12",
! "2001-08-14",
],
}PyYAML分析了所有的例子,就像我说我能读希腊语一样。我在70年代就学会了希腊语字母,这样我就能读懂希腊语(字符),但我不理解它们所构成的单词。
在ruamel.yaml (免责声明:我是该包的作者)中,您可以加载这个示例,甚至可以使用PyYAML转储加载的数据。
from pprint import pprint
import ruamel.yaml
import yaml as pyyaml
yaml = ruamel.yaml.YAML(typ='safe')
data = yaml.load(yaml_1_1_example_2_11)
pprint(data)
print('*' * 50)
yaml.dump(data, sys.stdout)
print('*' * 50)
pyyaml.safe_dump(data, sys.stdout)因为这意味着:
{('Detroit Tigers', 'Chicago cubs'): [datetime.date(2001, 7, 23)],
('New York Yankees', 'Atlanta Braves'): [datetime.date(2001, 7, 2),
datetime.date(2001, 8, 12),
datetime.date(2001, 8, 14)]}
**************************************************
? [Detroit Tigers, Chicago cubs]
: [2001-07-23]
? [New York Yankees, Atlanta Braves]
: [2001-07-02, 2001-08-12, 2001-08-14]
**************************************************
? [Detroit Tigers, Chicago cubs]
: [2001-07-23]
? [New York Yankees, Atlanta Braves]
: [2001-07-02, 2001-08-12, 2001-08-14]https://stackoverflow.com/questions/53995421
复制相似问题