首页 > 解决方案 > 使用 ruamel CommentedMap() 手动添加项目

问题描述

作为我之前的 [ Loading and dumping multiple yaml files with ruamel.yaml (python) question) 的后续,我现在正尝试将项目插入树中。我正在使用CommentedMaps(),因此我也可以在树中插入自己的锚点/引用。

代码的相关部分:如果还没有用户:树,我创建这个:

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

标签: python-2.7ruamel.yaml

解决方案


)您仅在配额行之后留下了手动包装“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)

推荐阅读