PyYAML yaml.dump()为字符串键生成复合键> 122个字符?

时间:2015-07-03 01:48:42

标签: python yaml pyyaml

使用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代码中不期望的视觉一致性缺乏,具体取决于字符串键的长度。

1 个答案:

答案 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增强版的作者。