Этого хука нет, создаваемый тип жестко запрограммирован в construct.BaseConstructor.construct_mapping()
.
Чтобы решить эту проблему, создайте свой собственный конструктор и на его основе свой собственный загрузчик и передайте его в качестве опции для load()
:
import sys
import collections
import ruamel.yaml as yaml
yaml_str = """\
level0:
stuff: string0
level1:
stuff: string1
level2: ...
"""
from ruamel.yaml.reader import Reader
from ruamel.yaml.scanner import Scanner
from ruamel.yaml.parser import Parser
from ruamel.yaml.composer import Composer
from ruamel.yaml.constructor import SafeConstructor
from ruamel.yaml.resolver import Resolver
from ruamel.yaml.nodes import MappingNode
class FancyDict(collections.MutableMapping):
def __init__(self, *args, **kwargs):
for name in kwargs:
setattr(self, name, kwargs[name])
# provide the missing __getitem__, __setitem__, __delitem__, __iter__, and __len__.
class MyConstructor(SafeConstructor):
def construct_mapping(self, node, deep=False):
res = SafeConstructor.construct_mapping(self, node, deep)
assert isinstance(res, dict)
return FancyDict(**res)
class MyLoader(Reader, Scanner, Parser, Composer, MyConstructor, Resolver):
def __init__(self, stream, version=None):
Reader.__init__(self, stream)
Scanner.__init__(self)
Parser.__init__(self)
Composer.__init__(self)
MyConstructor.__init__(self)
Resolver.__init__(self)
data = yaml.load(yaml_str, Loader=MyLoader)
Когда вы запустите это, вы получите сообщение об ошибке, что FancyDict - это абстрактный класс, который не может быть создан:
TypeError: невозможно создать экземпляр абстрактного класса FancyDict с абстрактными методами __delitem__
, __getitem__
, __iter__
, __len__
, __setitem__
Я предполагаю, что в вашем настоящем FancyDict
они реализованы.
ruamel.yaml - это библиотека YAML, которая поддерживает YAML 1.2 (я рекомендую использовать ее, но тогда я являюсь автором пакета). PyYAML поддерживает только (большую часть) YAML 1.1. Более проблематично то, что у него разные constructor.py
файлы для Python2 и Python3, из-за этого вы не сможете добавить приведенный выше код в PyYAML.
person
Anthon
schedule
14.04.2016