Il modo più semplice per eseguire questa operazione è probabilmente sovrascrivere il costruttore YAML per tag:yaml.org,2002:map
in modo che restituisca una classe dizionario personalizzata anziché un dizionario normale.
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
Si noti che questo si romperà tutto il resto del processo che utilizza YAML, se si aspetta di tutto per lavorare nel modo Python normale. È possibile utilizzare un caricatore personalizzato, ma personalmente trovo la documentazione PyYAML un po 'labirintica, e sembra che gli effetti collaterali siano globali e contagiosi come una regola piuttosto che un'eccezione.
Sei stato avvisato.
In alternativa, se lo schema è relativamente statico si potrebbe scrivere le proprie classi e deserializzare a quelli (ad esempio, con class Config
id
e name
proprietà). Probabilmente non varrebbe la pena il costo del codice extra, comunque.
fonte
2012-06-15 11:19:12
Duplicato di http://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary – Justin
@Justin: Questo non è un duplicato di questa domanda, perché puoi semplicemente applicare una patch al caricatore YAML per creare oggetti di qualunque classe desideri invece di istanze di 'dict'. –