Cách dễ nhất để làm điều này có lẽ là ghi đè lên hàm tạo YAML cho tag:yaml.org,2002:map
để nó trả về một lớp từ điển tùy chỉnh thay vì một từ điển thông thường.
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
Lưu ý rằng điều này sẽ phá vỡ mọi thứ khác trong quá trình sử dụng YAML, nếu nó mong muốn mọi thứ hoạt động bình thường theo cách Python. Bạn có thể sử dụng một bộ tải tùy chỉnh, nhưng cá nhân tôi tìm thấy tài liệu PyYAML một chút mê cung, và có vẻ như các tác dụng phụ là toàn cầu và dễ lây lan như một quy tắc hơn là một ngoại lệ.
Bạn đã được cảnh báo.
Là một thay thế, nếu schema của bạn là tương đối tĩnh bạn có thể viết các lớp học của riêng bạn và deserialize để những người (ví dụ, class Config
với id
và name
tài sản). Nó có lẽ sẽ không có giá trị chi phí của mã phụ, tuy nhiên.
Nguồn
2012-06-15 11:19:12
Bản sao của http://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary – Justin
@Justin: Đây không phải là bản sao của câu hỏi này, bởi vì bạn có thể chỉ cần vá bộ nạp YAML để tạo ra các đối tượng của bất kỳ lớp nào bạn mong muốn hơn là các trường hợp của 'dict'. –