私はカスタムPythonオブジェクトを作成するpythonでyamlシーケンスを作成しようとしています。オブジェクトは、__init__
の後に解体された辞書とリストで構築する必要があります。しかし、construct_mapping関数は組み込みシーケンス(リスト)とdictsのツリー全体を構築しないようです。
は、次のことを考えてみましょう:すべてのノードのロードが完了した後、PyYAML construct_mappingを使用してオブジェクトを構築する方法はありますか?
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
がFoo
オブジェクトが作成された後、実際にデータで満たされているl
とd
オブジェクトへの参照を保持しているので、これは正常に動作します。
それでは、ちょっぴりより複雑な何かをしてみましょう:
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
今、私たちはYAMLのコンストラクタは、前のネストの外側の層から開始されるので、これは、次のエラー
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
を取得し、すべてのノードが終了する前にオブジェクトを構築する。順序を逆にし、深く埋め込まれたオブジェクト(たとえば、ネストされたオブジェクト)を先に開始する方法はありますか?あるいは、ノードのオブジェクトがロードされた後に、少なくともの構築が行われる方法がありますか?
**ありがとうございました!**これにより、抜け毛がなくなりました。 –
私はこの男にもっと多くのポイントを与えることができたらいいと思う。 – Dacav
OMG!やっと ! – Penbeuz