कि सिद्धांत रूप में संभव है, क्योंकि आप कर सकते हैं राउंड ट्रिप इस तरह के "शुरू-ऑफ-द फ़ाइल" टिप्पणी है, लेकिन यह वर्तमान ruamel.yaml 0.10 में अच्छी तरह से समर्थित नहीं है और निश्चित रूप से नहीं जब "खरोंच से शुरू" (यानी कोई मौजूदा फ़ाइल नहीं बदल रहा है)। नीचे एक अपेक्षाकृत अच्छा समाधान है, लेकिन मैं सबसे पहले एक बदसूरत कामकाज पेश करना चाहता हूं और यह एक कदम-दर-चरण कैसे किया जाए।
Comment(comment=[None, [CommentToken(value=u'# Data for Class A\n')]],
items={})
Comment(comment=None,
items={})
एक Comment
: अगर आप c
import ruamel.yaml
from ruamel.yaml.comments import Comment, CommentedSeq, CommentedMap
d = CommentedMap() # <<<<< most important
for m in ['B1', 'B2', 'B3']:
d2 = {}
for f in ['A1', 'A2', 'A3']:
d2[f] = CommentedSeq(['test', 'test2'])
if f != 'A2':
d2[f].fa.set_flow_style()
d[m] = d2
yaml_str = ruamel.yaml.dump(d, Dumper=ruamel.yaml.RoundTripDumper,
default_flow_style=False, width=50, indent=8)
assert not hasattr(d, Comment.attrib) # no attribute on the CommentedMap
comment = 'Data for Class A'
commented_yaml_str = '# ' + comment + '\n' + yaml_str
c = ruamel.yaml.load(commented_yaml_str, Loader=ruamel.yaml.RoundTripLoader)
assert hasattr(c, Comment.attrib) # c has the attribute
print c.ca # and this is what it looks like
print d.ca # accessing comment attribute creates it empty
assert hasattr(d, Comment.attrib) # now the CommentedMap has the attribute
यह प्रिंट में वापस टिप्पणी की YAML लोड करके एक टिप्पणी है कि एक के साथ कि d
चर के अंतर की तुलना ईओएल टिप्पणी (हमेशा केवल एक) और पिछली पंक्ति टिप्पणियों की सूची (CommentTokens
के रूप में)
एक CommentToken बनाने के लिए आप एक (फर्जी) StartMark कि यह बताती है कि स्तंभ यह शुरू होता है की जरूरत है:
from ruamel.yaml.tokens import CommentToken
ct = CommentToken('# ' + comment + '\n', start_mark, None)
पूर्ववर्ती के पहले तत्व के रूप में टोकन असाइन करें:
from ruamel.yaml.error import Mark
start_mark = Mark(None, None, None, 0, None, None) # column 0
अब आप टोकन बना सकते हैं अपने CommentedMap पर सूची:
d.ca.comment = [None, [ct]]
print d.ca # in case you want to check
आप देता है:
Comment(comment=[None, [CommentToken(value='# Data for Class A\n')]],
items={})
और अंत में:
print ruamel.yaml.dump(d, Dumper=ruamel.yaml.RoundTripDumper)
देता है:
# Data for Class A
B1:
A1: [test, test2]
A3: [test, test2]
A2:
- test
- test2
B2:
A1: [test, test2]
A3: [test, test2]
A2:
- test
- test2
B3:
A1: [test, test2]
A3: [test, test2]
A2:
- test
- test2
बेशक आप c
वस्तु बनाने की जरूरत नहीं है के , यह सिर्फ उदाहरण के लिए है।
क्या आप उपयोग करना चाहिए: पूरी कवायद को कुछ हद तक आसान तुम सिर्फ विवरण और निम्न विधि में पैच के बारे में CommentedBase
एक बार करने के लिए भूल सकता है बनाने के लिए:
from ruamel.yaml.comments import CommentedBase
def set_start_comment(self, comment, indent=0):
"""overwrites any preceding comment lines on an object
expects comment to be without `#` and possible have mutlple lines
"""
from ruamel.yaml.error import Mark
from ruamel.yaml.tokens import CommentToken
if self.ca.comment is None:
pre_comments = []
self.ca.comment = [None, pre_comments]
else:
pre_comments = self.ca.comments[1]
if comment[-1] == '\n':
comment = comment[:-1] # strip final newline if there
start_mark = Mark(None, None, None, indent, None, None)
for com in comment.split('\n'):
pre_comments.append(CommentToken('# ' + com + '\n', start_mark, None))
if not hasattr(CommentedBase, 'set_start_comment'): # in case it is there
CommentedBase.set_start_comment = set_start_comment
और फिर बस कार्य करें:
d.set_start_comment('Data for Class A')
जो आसान था :) – user3214546