我想让PyYAML的加载器将映射(和有序映射)加载到Python 2.7+ OrderedDict类型中,而不是vanilla dict和它当前使用的对列表.
最好的方法是什么?
我试图在python中创建一个yaml序列,创建一个自定义的python对象.该对象需要使用之后解构的dicts和列表构建__init__.但是,似乎construct_mapping函数不构造嵌入序列(列表)和dicts的整个树.
考虑以下:
import yaml
class Foo(object):
def __init__(self, s, l=None, d=None):
self.s = s
self.l = l
self.d = d
def foo_constructor(loader, node):
values = loader.construct_mapping(node)
s = values["s"]
d = values["d"]
l = values["l"]
return Foo(s, d, l)
yaml.add_constructor(u'!Foo', foo_constructor)
f = yaml.load('''
--- !Foo
s: 1
l: [1, 2]
d: {try: this}''')
print(f)
# prints: 'Foo(1, {'try': 'this'}, [1, 2])'
Run Code Online (Sandbox Code Playgroud)
这工作得很好,因为f持有的引用l和d对象,这实际上是充满了数据之后的Foo对象被创建.
现在,让我们做一些更复杂的smidgen:
class Foo(object):
def __init__(self, …Run Code Online (Sandbox Code Playgroud) 我正在尝试输出然后从 YAML 解析回以下内容
import numpy as np
class MyClass(object):
YAMLTag = '!MyClass'
def __init__(self, name, times, zeros):
self.name = name
self._T = np.array(times)
self._zeros = np.array(zeros)
Run Code Online (Sandbox Code Playgroud)
YAML 文件看起来像
!MyClass:
name: InstanceId
times: [0.0, 0.25, 0.5, 1.0, 2.0, 5.0, 10.0]
zeros: [0.03, 0.03, 0.04, 0.03, 0.03, 0.02, 0.03]
Run Code Online (Sandbox Code Playgroud)
为了编写,我在类中添加了两个方法
def toDict(self):
return {'name' : self.name,
'times' : [float(t) for t in self._T],
'zeros' : [float(t) for t in self._zeros]}
@staticmethod
def ToYAML(dumper, data):
return dumper.represent_dict({data.YAMLTag : data.toDict()})
Run Code Online (Sandbox Code Playgroud)
并阅读,方法
@staticmethod
def FromYAML(loader, …Run Code Online (Sandbox Code Playgroud) 我们需要解析包含重复密钥的YAML文件,而所有这些都需要解析。跳过重复项是不够的。我知道这违反了YAML规范,我不想这样做,但是我们使用的第三方工具可以启用此用法,因此我们需要对其进行处理。
文件示例:
build:
step: 'step1'
build:
step: 'step2'
Run Code Online (Sandbox Code Playgroud)
解析之后,我们应该具有与此类似的数据结构:
yaml.load('file.yml')
# [('build', [('step', 'step1')]), ('build', [('step', 'step2')])]
Run Code Online (Sandbox Code Playgroud)
dict 不能再用于表示已解析的内容。
我正在寻找Python中的解决方案,但没有找到支持此功能的库,是否错过了任何内容?
另外,我很乐于写自己的东西,但想使其尽可能简单。ruamel.yaml看起来像Python中最先进的YAML解析器,并且看起来具有一定程度的可扩展性,是否可以扩展以支持重复字段?