La forma más sencilla de hacerlo es, probablemente, sobrescribir el constructor YAML para tag:yaml.org,2002:map
, por lo que devuelve una clase de diccionario personalizada en lugar de un diccionario normal.
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
Tenga en cuenta que esto va a romper todo lo demás en el proceso que utiliza YAML, si se espera que todo funcione de la manera normal de Python. Puede usar un cargador personalizado, pero personalmente encuentro que la documentación PyYAML es un poco laberíntica, y parece que los efectos colaterales son globales y contagiosos como una regla en lugar de una excepción.
Has sido advertido.
Como alternativa, si el esquema es relativamente estática podría escribir sus propias clases y deserializar a aquellos (por ejemplo, class Config
con id
y name
propiedades). Sin embargo, probablemente no valdría la pena el costo del código adicional.
Duplicado de http://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary – Justin
@Justin: Esto no es un duplicado de esta pregunta, porque simplemente puede parchear el cargador YAML para crear objetos de cualquier clase que desee en lugar de instancias de 'dict'. –