我试图了解有关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规范吗?
答案 0 :(得分:4)
首先要回答的最后一个问题:由于示例,这不是不是 来自更高的规范。假设您限制自己 规范中的“预览”一章/部分(在线解析器也是如此), 考虑到我只是比较了例子 这些示例在视觉上(即,不是以角色为基础) 第2章的1.2和1.1规范中的内容相同。
您的误解是由于在 在线解析器的标题。它实际尝试做的是 load YAML,然后转储到JSON,Python或规范YAML。 loading 在 PyYAML包含YAML Processing Overview图片中提到的阶段 规范(与1.1和1.2相同),从基于字符开始 文档:解析,组成和构建步骤。
PyYAML不会在解析步骤中失败,而是在构造时失败
步骤,因为(如@torek所示)PyYAML构造了一个list
,并且
不能用作Python dict
的键。这是一个
限制Python dict
的实现和IMO是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]