<p>首先,除非默认文件中有多个文档,否则
不必使用<code>load_all</code>,因为您不需要将两个文档连接到
多文档流。如果你用一个带文档结尾的格式字符串
标记(<code>"{}\n...\n{}"</code>)或带有指令结束标记(<code>"{}\n -\n{}"</code>)
你的别名不会从一个文档传递到另一个文档
YAML规格:</p>
<blockquote>
<p>It is an error for an alias node to use an anchor that does not
previously occur in the document.</p>
</blockquote>
<p>锚定必须在文档中,而不仅仅是在流中(流可以由多个
文件)。</p>
<hr/>
<p>我尝试了一些hocus pocus,预先填充已经呈现的字典
锚定节点数:</p>
<pre><code>import sys
import datetime
from ruamel import yaml
def load():
with open('defaults.yaml') as fp:
defaults_data = fp.read()
with open('user.yaml') as fp:
user_data = fp.read()
merged_data = yaml.load("{}\n{}".format(defaults_data, user_data),
Loader=yaml.RoundTripLoader)
return merged_data
class MyRTDGen(object):
class MyRTD(yaml.RoundTripDumper):
def __init__(self, *args, **kw):
pps = kw.pop('pre_populate', None)
yaml.RoundTripDumper.__init__(self, *args, **kw)
if pps is not None:
for pp in pps:
try:
anchor = pp.yaml_anchor()
except AttributeError:
anchor = None
node = yaml.nodes.MappingNode(
u'tag:yaml.org,2002:map', [], flow_style=None, anchor=anchor)
self.represented_objects[id(pp)] = node
def __init__(self, pre_populate=None):
assert isinstance(pre_populate, list)
self._pre_populate = pre_populate
def __call__(self, *args, **kw):
kw1 = kw.copy()
kw1['pre_populate'] = self._pre_populate
myrtd = self.MyRTD(*args, **kw1)
return myrtd
def update(md, file_name):
ud = md.pop('userdefaults')
MyRTD = MyRTDGen([ud])
yaml.dump(md, sys.stdout, Dumper=MyRTD)
with open(file_name, 'w') as fp:
yaml.dump(md, fp, Dumper=MyRTD)
md = load()
md['users']['xxxx2']['timestamp'] = str(datetime.datetime.utcnow())
update(md, 'user.yaml')
</code></pre>
<p>由于基于PyYAML的API需要一个类而不是一个对象,因此您需要
使用一个类生成器,它实际上添加了要预填充的数据元素
这只苍蝇来自于<code>yaml.load()</code>。</p>
<p>但这不起作用,因为节点只有在锚定之后才能被写出
确定使用了锚点(即有第二个参考)。所以实际上
第一个合并键被写为锚。虽然我很熟悉
有了代码库,我无法在合理的时间内使其正常工作。</p>
<p>因此,我只能依赖于只有一个匹配的键
在组合更新的转储的根级别上<code>users.yaml</code>的第一个键
在那之前把任何东西锉掉。</p>
^{pr2}$
<p>它给出了:</p>
<pre><code>users:
xxxx1:
<<: *userdefaults
timestamp: '2018-10-22 11:38:28.541810'
xxxx2:
<<: *userdefaults
timestamp: '2018-10-23 09:59:13.829978'
</code></pre>
<hr/>
<p>我必须制作一个virtualenv来确保我可以用<code>ruamel.yaml==0.13.14</code>运行上面的内容。
这个版本是从我还年轻的时候开始的(我不会声称自己是无辜的)。
从那时起,这个库已经发行了超过85个版本。</p>
<p>我能理解,你可能什么都不能做
Python2目前无法编译/使用更新的版本。但是什么
您真正应该做的是安装<code>virtualenv</code>(可以使用EPEL完成,但也可以不使用
进一步“污染”您的系统安装),为
您正在开发并安装最新版本的<code>ruamel.yaml</code>(和
你的其他图书馆)在那里。你也可以这样做,如果你需要
要将软件分发到其他系统,只需在那里安装virtualenv。</p>
<p>我把我所有的实用程序都放在<code>/opt/util</code>下,并进行管理
<a href="https://pypi.org/project/virtualenvutils/" rel="nofollow noreferrer">^{<cd10>}</a>a
包装virtualenv。</p>