使用PyYAML 3.11和Python 2.7.6,让我们转储一个只有一个字符串键(长度为122个字符)的简单字典,映射到值' 1':
>>> print yaml.dump({'12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012': 1})
{'12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012': 1}
这与预期一样 - 简单,人类可读的YAML。但现在让我们将该字符串键的长度增加到123个字符。现在,PyYAML创建了一个人类可读的复杂键,从"?"开始,它分流值#34; 1"在一条新线上:
>>> print yaml.dump({'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123': 1})
{? '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123'
: 1}
为什么PyYAML会这样做?有没有办法禁用这种行为?它导致我的转储YAML代码中不期望的视觉一致性缺乏,具体取决于字符串键的长度。
答案 0 :(得分:2)
您获得显式键标记?
的原因是您超过了简单键的长度限制。这在发射器中的函数中与128进行比较(隐式标记!!str
的长度将其推过该阈值)。您可以重写检查键的完整函数是否简单,但没有简单的方法可以这样做,因为值在函数内是硬编码的。
我始终无法在YAML spec中找到此特定阈值的原因。也不是在PyYAML源代码中,因为在解析器方面,它能够处理这样的长键(有或没有?
)。
在ruamel.yaml¹中,您可以通过更改转储器实例来更改阈值:
from __future__ import print_function
import sys
import ruamel.yaml as yaml
yaml_str = """\
- {'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123': 1}
"""
data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)
dumper = yaml.RoundTripDumper
print('MAX_SIMPLE_KEY_LENGTH', dumper.MAX_SIMPLE_KEY_LENGTH)
yaml.dump(data, sys.stdout, Dumper=dumper)
dumper.MAX_SIMPLE_KEY_LENGTH = 256
print('After raising the threshold:')
yaml.dump(data, sys.stdout, Dumper=dumper)
会给你:
MAX_SIMPLE_KEY_LENGTH 128
- {? '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123'
: 1}
After raising the threshold:
- {'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123': 1}
由于我通常在80列的终端窗口上工作,我仍然会发现很难读取的键,当然是YMMV。特别是在往返YAML时,需要对键的更改进行精确控制。
¹免责声明:我是PyYAML增强版的作者。