Ich versuche, verankerte Daten durch einen Konstruktor in einem Alias verwendet, aber der Alias möchte die Pre-Konstruktor Daten verwenden.mit einem Pyyaml oder Ruamel.Yaml-Konstruktor als Achor für einen Alias
Ich habe Inspiration von Anthon Is there a way to construct an object using PyYAML construct_mapping after all nodes complete loading? genommen, aber immer noch keine Freude gefunden.
Nachfolgend finden Sie einige Beispielcode:
class L2D(dict):
def __repr__(self):
return('L2D({})'.format(dict.__repr__(self)))
def l2d_constructor(loader, node):
print("constructing")
instance = L2D.__new__(L2D)
yield instance
state = loader.construct_sequence(node, deep=True)
instance.__init__(state)
yaml.add_constructor(u'!l2d', l2d_constructor)
print(yaml.load('''
a: !l2d
- [e, f]
- [g, h]
'''))
print("============")
print(yaml.load('''
a: &other !l2d
- [e, f]
- [g, h]
b:
<<: *other
a: b
c: d
'''))
Die ersten Arbeiten Last aber während ich die zweite Lasten Ausgang
constructing
{'a': L2D({'g': 'h', 'e': 'f'}), 'b': {'a': 'b', 'g': 'h', 'e': 'f', 'c': 'd'}}
statt I
constructing
Traceback (most recent call last):
File "test2.py", line 41, in <module>
'''))
File "/tmp/tmp.1oRXCix7X3/venv/lib/python3.5/site-packages/ruamel/yaml/main.py", line 86, in load
return loader.get_single_data()
File "/tmp/tmp.1oRXCix7X3/venv/lib/python3.5/site-packages/ruamel/yaml/constructor.py", line 56, in get_single_data
return self.construct_document(node)
File "/tmp/tmp.1oRXCix7X3/venv/lib/python3.5/site-packages/ruamel/yaml/constructor.py", line 65, in construct_document
for dummy in generator:
File "/tmp/tmp.1oRXCix7X3/venv/lib/python3.5/site-packages/ruamel/yaml/constructor.py", line 494, in construct_yaml_map
value = self.construct_mapping(node)
File "/tmp/tmp.1oRXCix7X3/venv/lib/python3.5/site-packages/ruamel/yaml/constructor.py", line 265, in construct_mapping
self.flatten_mapping(node)
File "/tmp/tmp.1oRXCix7X3/venv/lib/python3.5/site-packages/ruamel/yaml/constructor.py", line 240, in flatten_mapping
% subnode.id, subnode.start_mark)
ruamel.yaml.constructor.ConstructorError: while constructing a mapping
in "<unicode string>", line 8, column 3:
<<: *other
^(line: 8)
expected a mapping for merging, but found sequence
in "<unicode string>", line 5, column 5:
- [e, f]
^(line: 5)
bekommen zu erwarten wäre Der Druck constructing
schlägt vor, dass der Konstruktor seine Arbeit getan hat, aber mein Verdacht ist, dass der Alias es versucht, die Daten aus dem unveränderten Yaml-Baum zu erhalten, anstatt die resultierenden Daten aus dem Konstruktor.
Gibt es eine Möglichkeit, wie ich das schaffen kann?
Ich verstehe, wie die Mapping-Funktion funktioniert, das '! L2d'-Tag und' l2d_constructor'-Funktion ändert die 'a'-Sequenz in ein dict, wie Sie im resultierenden Python-Objekt sehen können. Meine Hoffnung war, dass die Mutation der Konstruktorfunktion von Sequenz zu Mapping bedeuten würde, dass ich den 'a'-Wert wie ein Mapping im yaml behandeln könnte, aber ich denke immer mehr, dass es zu diesem Zeitpunkt im Parsing zu spät ist <'wird vor'! l2d' und der entsprechenden Konstruktorfunktion verarbeitet. – tommyvn
Ja, das Übersetzen wird vom Parser ausgeführt, es dauert nicht die Sequenz, was das Tag daraus gemacht hat. Eine Sache, die Sie tun können, ist die '' '' in etwas anderes, das eindeutig ist (z. B. '>>') und markieren Sie die Zuordnung, um ein Diktat wie Objekt zu laden, das den Wert für '>>' interpretiert. Oder Sie können die Zusammenführungsfunktion in 'constructor.py' ersetzen, um das Richtige zu tun. – Anthon