अपने उदाहरण अमान्य है यही कारण है केवल क्योंकि आप एक आरक्षित वर्ण के साथ अपने scalars शुरू करने के लिए चुना है। यदि आप *
कुछ अन्य गैर-आरक्षित वर्ण के साथ प्रतिस्थापित करते हैं (मैं गैर-ASCII वर्णों का उपयोग करने के लिए हूं क्योंकि वे शायद ही कभी कुछ विनिर्देश के भाग के रूप में उपयोग किए जाते हैं), तो आप पूरी तरह से कानूनी यम के साथ समाप्त होते हैं:
paths:
root: /path/to/root/
patha: ♦root♦ + a
pathb: ♦root♦ + b
pathc: ♦root♦ + c
यह आपके पार्सर द्वारा उपयोग की जाने वाली भाषा में मैपिंग के लिए मानक प्रतिनिधित्व में लोड होगा और जादुई रूप से किसी चीज़ का विस्तार नहीं करता है।
निम्न पायथन प्रोग्राम के अनुसार स्थानीय रूप से डिफ़ॉल्ट ऑब्जेक्ट प्रकार का उपयोग करने के लिए:
# coding: utf-8
from __future__ import print_function
import ruamel.yaml as yaml
class Paths:
def __init__(self):
self.d = {}
def __repr__(self):
return repr(self.d).replace('ordereddict', 'Paths')
@staticmethod
def __yaml_in__(loader, data):
result = Paths()
loader.construct_mapping(data, result.d)
return result
@staticmethod
def __yaml_out__(dumper, self):
return dumper.represent_mapping('!Paths', self.d)
def __getitem__(self, key):
res = self.d[key]
return self.expand(res)
def expand(self, res):
try:
before, rest = res.split(u'♦', 1)
kw, rest = rest.split(u'♦ +', 1)
rest = rest.lstrip() # strip any spaces after "+"
# the lookup will throw the correct keyerror if kw is not found
# recursive call expand() on the tail if there are multiple
# parts to replace
return before + self.d[kw] + self.expand(rest)
except ValueError:
return res
yaml_str = """\
paths: !Paths
root: /path/to/root/
patha: ♦root♦ + a
pathb: ♦root♦ + b
pathc: ♦root♦ + c
"""
loader = yaml.RoundTripLoader
loader.add_constructor('!Paths', Paths.__yaml_in__)
paths = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)['paths']
for k in ['root', 'pathc']:
print(u'{} -> {}'.format(k, paths[k]))
जो प्रिंट करेगा:
root -> /path/to/root/
pathc -> /path/to/root/c
विस्तार मक्खी पर किया जाता है और नेस्टेड परिभाषाओं को संभालता है, लेकिन आपको अनंत पुनरावृत्ति न करने के बारे में सावधान रहना होगा।
डम्पर को निर्दिष्ट करके, आप ऑन-द-फ्लाई विस्तार के कारण लोड किए गए डेटा से मूल YAML को डंप कर सकते हैं:
dumper = yaml.RoundTripDumper
dumper.add_representer(Paths, Paths.__yaml_out__)
print(yaml.dump(paths, Dumper=dumper, allow_unicode=True))
यह मैपिंग कुंजी को बदल देगा। यदि यह एक समस्या है तो आपको self.d
एक CommentedMap
(से आयातित ruamel.yaml.comments.py
) बनाना होगा