Самый простой способ сделать это, вероятно, перезаписать конструктор YAML для tag:yaml.org,2002:map
, чтобы он возвращал пользовательский класс словаря вместо обычного словаря.
import yaml
class AttrDict(object):
def __init__(self, attr):
self._attr = attr
def __getattr__(self, attr):
try:
return self._attr[attr]
except KeyError:
raise AttributeError
def construct_map(self, node):
# WARNING: This is copy/pasted without understanding!
d = {}
yield AttrDict(d)
d.update(self.construct_mapping(node))
# WARNING: We are monkey patching PyYAML, and this will affect other clients!
yaml.add_constructor('tag:yaml.org,2002:map', construct_map)
YAML = """
config:
- id: foo
- name: bar
content:
- run: xxx
- remove: yyy
"""
obj = yaml.load(YAML)
print(obj.config[0].id) # prints foo
Обратите внимание, что это нарушит все остальное в процессе, который использует YAML, если он ожидает, что все будет работать обычным способом Python. Вы можете использовать собственный загрузчик, но я лично нахожу документацию PyYAML немного запутанной, и кажется, что побочные эффекты являются глобальными и заразными, как правило, а не исключение.
Вы были предупреждены.
В качестве альтернативы, если ваша схема относительно статична, вы можете написать свои собственные классы и десериализовать их (например, class Config
со свойствами id
и name
). Однако, вероятно, это не стоило бы затрат на дополнительный код.
person
Dietrich Epp
schedule
15.06.2012
dict
. - person Dietrich Epp   schedule 15.06.2012