Ich versuche, eine YAML-Sequenz in Python zu erstellen, die ein benutzerdefiniertes Python-Objekt erstellt. Das Objekt muss mit Dicts und Listen erstellt werden, die nach __init__
dekonstruiert werden. Es scheint jedoch, dass die construct_mapping-Funktion nicht den gesamten Baum der eingebetteten Sequenzen (Listen) und dicts erstellt.
Beachten Sie Folgendes:Gibt es eine Möglichkeit, ein Objekt mithilfe von PyYAML construct_mapping zu erstellen, nachdem alle Knoten vollständig geladen wurden?
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])'
Dies funktioniert gut, weil f
die Verweise auf die l
und d
Objekte enthält, die mit Daten tatsächlich gefüllt sind nach das Foo
Objekt erstellt wird.
Jetzt wollen wir etwas tun, ein ganz klein wenig komplizierter:
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
Jetzt bekommen wir die Fehler folgende
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
Dies ist, weil der yaml Konstruktor wird vor der Verschachtelung an der äußeren Schicht beginnt und Konstruieren des Objekts, bevor alle Knoten beendet sind. Gibt es eine Möglichkeit, die Reihenfolge umzukehren und zuerst mit tief eingebetteten (z. B. verschachtelten) Objekten zu beginnen? Alternativ gibt es eine Möglichkeit, um die Konstruktion zu erreichen, mindestens nach die Objekte des Knotens wurden geladen?
** Danke! ** Das ersparte mir ein paar ausgezogene Haare. –
Ich wünschte, ich könnte diesem Typ mehr Punkte geben. – Dacav
OMG! zu guter Letzt !Ich würde dich für diesen Post küssen :-) – Penbeuz