使用 ruamel CommentedMap() 手动添加项目

Manually adding items using ruamel CommentedMap()

作为我之前 [ 问题的后续问题),我现在正在尝试将项目插入到树中。我正在使用 CommentedMaps(),这样我也可以在树中插入我自己的 anchors/references。

代码的相关部分: 如果没有 users: tree 存在,我创建这个:

if 'users' not in merged_yaml:
    merged_yaml['users'] = [ CommentedMap() ]
    merged_yaml['users'][0].yaml_set_anchor('users')

然后像这样添加它们

merged_yaml['users'][0][user_name] = CommentedMap({'timestamp': current_date}, relax=True)
merged_yaml['users'][0][user_name].add_yaml_merge([(0, userdefaults)])

所以,虽然这有效,但我得到了不一致的结果,如您所见(输出 pprint(merged_yaml['users']) - 手动缩进)。问题出在 user3 被合并到 user2 的映射中。

[ordereddict([
    ('user1', ordereddict([
        ('timestamp', '2018-10-25 11:16:42.132415'), 
        ('files', 1000), 
        ('quota', 200)
    ])), 
    ('user2', ordereddict([
        ('timestamp', '2018-10-25 11:16:42.132415'), 
        ('files', 1000), 
        ('quota', 200)
     ])), 
     ('user3', ordereddict([
         ('timestamp', '2018-10-25 11:16:42.132415'), 
         ('files', 1000), 
         ('quota', 200)
     ]))
    ])
]

我一直在试图弄清楚我做错了什么,但我无法发现它。

users:
-   user1:
        <<: *userdefaults
        timestamp: '2018-10-25 11:16:42.132415'
    user2:
        <<: *userdefaults
        timestamp: '2018-10-25 11:16:42.132415'
    user3:
        <<: *userdefaults
        timestamp: '2018-10-25 11:16:42.132415'

我期待的是:

[ordereddict([
    ('user1', ordereddict([
    ....
    ]))
]),
ordereddict([
    ('user2', ordereddict([
    ....
    ]))
])
]

users:
-   user1:
        <<: *userdefaults
        timestamp: '2018-10-25 11:16:42.132415'
-    user2:
        <<: *userdefaults
        timestamp: '2018-10-25 11:16:42.132415'
-    user3:
        <<: *userdefaults
        timestamp: '2018-10-25 11:16:42.13241

您通过仅在配额行后留下 ) 来手动换行 "user1"。 如果您对 "user2" 的配额行执行相同操作,并将 "user3" 的配额放在换行符上,您会看到缩进 让您在解释输出时失去平衡。

[ordereddict([
    ('user1', ordereddict([
        ('timestamp', '2018-10-25 11:16:42.132415'), 
        ('files', 1000), 
        ('quota', 200)
    ])), 
#     ^ closing for tuple
#    ^ closing for ordereddict
#   ^ closing for list of ordereddict tuples
    ('user2', ordereddict([
        ('timestamp', '2018-10-25 11:16:42.132415'), 
        ('files', 1000), 
        ('quota', 200)
    ])), 
        ('user3', ordereddict([
            ('timestamp', '2018-10-25 11:16:42.132415'), 
            ('files', 1000), 
            ('quota', 200)
        ]))
#   ^^^^ extra indent in 5 preceding lines
    ])
]

根据预期输出,您希望每个序列元素有一个映射,而您的序列有多个元素。为此,在 Python 中,您需要将 CommentedMap 附加到列表中:

merged_yaml['users'] = x = []
for user in users:
   cm = CommentedMap()
   cm[user] = CommentedMap({'timestamp': current_date}, relax=True)
   cm.add_yaml_merge([(0, userdefaults)])    
   x.append(cm)