Najprostszym sposobem na to jest prawdopodobnie nadpisanie konstruktora YAML dla tag:yaml.org,2002:map
, więc zwraca on niestandardową klasę słownika zamiast zwykłego słownika.
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
Zauważ, że to złamie wszystkiego innego w procesie, który używa YAML, jeśli spodziewa się wszystko do pracy normalnej Pythona sposób. Możesz użyć niestandardowego programu ładującego, ale osobiście uważam dokumentację PyYAML za nieco labirynt i wydaje się, że skutki uboczne są globalne i zakaźne z reguły, a nie jako wyjątek.
Zostałeś ostrzeżony.
Jako alternatywę jeśli schemat jest względnie statyczne można napisać własne klasy i deserializowania osobom (np class Config
z id
i name
właściwości). Prawdopodobnie nie byłby jednak wart kosztu dodatkowego kodu.
Duplikat http://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary – Justin
@Justin: To nie jest duplikat tego pytania, ponieważ możesz po prostu załatać program ładujący YAML, aby tworzyć obiekty dowolnej klasy, a nie instancji 'dyktowania'. –