<p>YAML可以用多种方式将字符串表示为标量:普通(不带引号)、单引号、双引号、带文本或折叠样式。键<code>sshkey</code>的值是纯标量。在</p>
<p>YAML也希望可读,而长行不是很可读。所以这里有一些规则,如何用宽标量来包装长线。您的普通标量即<code>sshkey</code>的值被包装。这意味着在YAML文档中有一个新行,但是在它所表示的标量字符串中没有新行,并且在读取YAML文档时,新行被“展开”。在</p>
<p>通过使用<code>yamldict</code>定义运行以下命令可以看到这一点:</p>
<pre><code>with open('tmp.yaml', 'w') as fp:
yaml.safe_dump(yamldict, fp)
with open('tmp.yaml') as fp:
data = yaml.safe_load(fp)
assert '\n' in data['users'][0]['sshkey']
</code></pre>
<p>这将抛出一个错误,因为重新加载的ssh密钥中没有新行。在</p>
<p>所以你的程序很好,但是你犯的错误是你没有阅读YAML规范,特别是<a href="http://yaml.org/spec/1.2/spec.html#id2779048" rel="nofollow noreferrer">line folding</a>上的部分。在</p>
<hr/>
<p>现在这种特殊的折叠并不能真正使内容更具可读性,因为ssh密钥中没有足够的空间。所以你可以增加线宽,把所有的东西都放在一条线上。您可以使用PyYAML来实现这一点,但我建议您使用<a href="https://pypi.org/project/ruamel.yaml/" rel="nofollow noreferrer">^{<cd4>}</a>,它支持更新的yaml1.2标准,允许映射和序列的单独缩进值,并且修复了许多PyYAML问题(免责声明:我是该包的作者):</p>
^{pr2}$
<p>此转储为:</p>
<pre><code>users:
- username: user
name: user
sshkey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHV/xbvOHuPq6WbBhtmjUWKYPrqQlkILf8b/I6V9dZVBPzmhRZFCAf/gWny0hmZ95bVRED4iCSTCtN3Lq2VZiZ/kwBO7Y9E4vr1wVQYrr4IIwEhdaifZmWFLlwOXbt76dxJQs2xS9Z5ZQjEzZBFZqgYu42QbSi7tKBNSaLadOWbB3sq0IOzCZeSgrELlZIuUy7u1RbcS4w2Y29S3XLrbi2yVdVbPW8B9PfsG1n4q2/XR7w3gqhP6c8ibO4jYpADLZuHZvuoVpjKINO4kSdrwUfD8rl3MBIAD/Nu9sy0bIiKdSONQohxcsjMevxPOijjz4EiI1Ad4U6dDJrFlT0asYH user@email.com
</code></pre>
<p>您可以做的另一件事是将该键作为文本样式标量转储。为此,您需要包含一个import:<code>from ruamel.yaml.scalarstring import PreservedScalarString</code>,然后在从MySQL读取数据后,在某处将密钥定义为保留标量字符串。在你的例子中,你可以这样做:</p>
<pre><code>for m in yamldict['users']:
m['sshkey'] = PreservedScalarString(m['sshkey'])
</code></pre>
<p>假设您删除了<code>yaml.width = 1024</code>,并包含了<code>yaml.indent(sequence=4, offset=2)</code>,那么这个转储将如下所示:</p>
<pre><code>users:
- username: user
name: user
sshkey: |-
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHV/xbvOHuPq6WbBhtmjUWKYPrqQlkILf8b/I6V9dZVBPzmhRZFCAf/gWny0hmZ95bVRED4iCSTCtN3Lq2VZiZ/kwBO7Y9E4vr1wVQYrr4IIwEhdaifZmWFLlwOXbt76dxJQs2xS9Z5ZQjEzZBFZqgYu42QbSi7tKBNSaLadOWbB3sq0IOzCZeSgrELlZIuUy7u1RbcS4w2Y29S3XLrbi2yVdVbPW8B9PfsG1n4q2/XR7w3gqhP6c8ibO4jYpADLZuHZvuoVpjKINO4kSdrwUfD8rl3MBIAD/Nu9sy0bIiKdSONQohxcsjMevxPOijjz4EiI1Ad4U6dDJrFlT0asYH user@email.com
</code></pre>
<p>其中<code>|-</code>表示文本样式的块标量。在</p>
<hr/>
<p>如果您需要坚持使用PyYAML,那么使用<code>safe_dump(yamldict, ..., width=1024)</code>,但是没有一种简单的方法可以将键作为文本样式的块标量转储,也不能只缩进序列)。在</p>