2016-05-01 9 views
3

これはthis SO questionに関連していると私は理解していますが、私が主に心配しているのは、これが保存されたコメントなどのものを混乱させるかどうかということです。ruamel.yamlのCommentedMapに行を挿入できますか?

import ruamel.yaml as yaml 

yaml_str = """\ 
first_name: Art 
occupation: Architect # This is an occupation comment 
about: Art Vandelay is a fictional character that George invents... 
""" 

data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader) 

# I'd like to extend CommentedMap so that I can do something like: 
data.insert(1, 'last_name', 'Vandelay') 

print(yaml.dump(data, Dumper=yaml.RoundTripDumper)) 
べき出力:Pythonの2.7で
first_name: Art 
last_name: Vandelay # This is an occupation comment 
occupation: Architect 
about: Art Vandelay is a fictional character that George invents... 

答えて

2

、および少なくともruamel.yaml 0.11.11とPythonの3.X上で、これは正常に動作します:

first_name: Art 
last_name: Vandelay 
occupation: Architect # This is an occupation comment 
about: Art Vandelay is a fictional character that George invents... 
ない出力する必要があります。

import ruamel.yaml 

yaml_str = """\ 
first_name: Art 
occupation: Architect # This is an occupation comment 
about: Art Vandelay is a fictional character that George invents... 
""" 

data = ruamel.yaml.round_trip_load(yaml_str) 
data.insert(1, 'last name', 'Vandelay') 

print(ruamel.yaml.round_trip_dump(data)) 

ができます:

first_name: Art 
last name: Vandelay 
occupation: Architect # This is an occupation comment 
about: Art Vandelay is a fictional character that George invents... 

は、行末コメントとしてCommentedMapの行のキーに関連付けられています。 (ruamel.yaml 0.11.10とLinuxのミント上のPython 2.7.11。)

.insert()使用しているが、本格的なruamel.ordereddictの特徴であるように、これはのpython3とruamel.yamlの古いバージョンでは動作しませんし、標準ライブラリのOrderedDictにはそのメソッドがありません。したがって、あなたはCommentedMap.insert()機能を移植する必要があります。

import ruamel.yaml 
from ruamel.yaml.comments import CommentedMap 
from ruamel.yaml.compat import ordereddict 

yaml_str = """\ 
first_name: Art 
occupation: Architect # This is an occupation comment 
about: Art Vandelay is a fictional character that George invents... 
""" 

def com_insert(self, pos, key, value, comment=None): 
    od = ordereddict() 
    od.update(self) 
    for k in od: 
     del self[k] 
    for index, old_key in enumerate(od): 
     if pos == index: 
      self[key] = value 
     self[old_key] = od[old_key] 
    if comment is not None: 
     self.yaml_add_eol_comment(comment, key=key) 

CommentedMap.insert = com_insert 

data = ruamel.yaml.round_trip_load(yaml_str) 
data.insert(1, 'last name', 'Vandelay', comment="new key") 

print(ruamel.yaml.round_trip_dump(data)) 

はのpython3になります:

first_name: Art 
last name: Vandelay # new key 
occupation: Architect # This is an occupation comment 
about: Art Vandelay is a fictional character that George invents... 

を新しくコメントを指定することができますinsert()ためのオプションパラメータがあることに注意してください挿入されたキーと値のペア。上記の動作はCommentedMapからキーを削除しても、そのキーに関連付けられているコメントは削除されないためです。だから私は、一時的にod で古いキーと値のペアは、すべてのキーの値を削除して駐車した後、適切なタイミングで新しいものを挿入してコピーバック

上記insertは、コメントで、ruamel.yamlに追加されました 用0.11.11両方のPython 2及び3


.round_trip_load()は、 `の.dump(.....、ダンパー= ruamel.yaml.RoundTripDumper、allow_unicode = Trueに.load(...., Loader=ruamel.yaml.RoundTripLoader, ...).round_trip_dump()に相当し、.. 。)

+0

何を待つ?私はruamel.ordereddictが '.insert()'を持っているのを知りませんでした:D – demux

+1

それは許されるものですが、アクセシブルな文書を書くことに関して、そのパッケージの作者は怠け者であることはよく知られています。 – Anthon

+0

私はそれがまったく利用できてうれしいです。ありがとうございました!しかし、 'Python 3 'を使っていても、何とか' ruamel.ordereddict'を使うことができますか? – demux

関連する問題