gpt4 book ai didi

python - 有没有办法在所有节点完成加载后使用 PyYAML construct_mapping 构造对象?

转载 作者:太空狗 更新时间:2023-10-29 17:01:21 24 4
gpt4 key购买 nike

我正在尝试在 python 中创建一个创建自定义 python 对象的 yaml 序列。该对象需要使用在 __init__ 之后解构的字典和列表来构造。但是,construct_mapping 函数似乎并没有构建整个嵌入序列(列表)和dict 的树。
请考虑以下事项:

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])'

这很好用,因为 f 保存了对 ld 对象的引用,这些对象实际上在 Foo 对象已创建。

现在,让我们做一些更复杂的事情:

class Foo(object):
def __init__(self, s, l=None, d=None):
self.s = s
# assume two-value list for l
self.l1, self.l2 = l
self.d = d

现在我们得到以下错误

Traceback (most recent call last):
File "test.py", line 27, in <module>
d: {try: this}''')
File "/opt/homebrew/lib/python2.7/site-packages/yaml/__init__.py", line 71, in load
return loader.get_single_data()
File "/opt/homebrew/lib/python2.7/site-packages/yaml/constructor.py", line 39, in get_single_data
return self.construct_document(node)
File "/opt/homebrew/lib/python2.7/site-packages/yaml/constructor.py", line 43, in construct_document
data = self.construct_object(node)
File "/opt/homebrew/lib/python2.7/site-packages/yaml/constructor.py", line 88, in construct_object
data = constructor(self, node)
File "test.py", line 19, in foo_constructor
return Foo(s, d, l)
File "test.py", line 7, in __init__
self.l1, self.l2 = l
ValueError: need more than 0 values to unpack

这是因为yaml的构造函数是从嵌套的外层开始的,在所有节点都完成之前构造对象。有没有办法颠倒顺序并首先从深度嵌入(例如嵌套)的对象开始?或者,有没有一种方法可以让构造至少在 节点的对象已加载之后发生?

最佳答案

嗯,你知道什么。我找到的解决方案非常简单,但没有很好的记录。

Loader class documentation清楚地表明 construct_mapping 方法只接受一个参数(node)。然而,在考虑编写自己的构造函数之后,我查看了源代码,答案是right there。 !该方法还接受一个参数 deep(默认为 False)。

def construct_mapping(self, node, deep=False):
#...

所以,正确的构造函数方法是

def foo_constructor(loader, node):
values = loader.construct_mapping(node, deep=True)
#...

我想 PyYaml 可以使用一些额外的文档,但我很感激它已经存在。

关于python - 有没有办法在所有节点完成加载后使用 PyYAML construct_mapping 构造对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19439765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com