Python 3.x PyYaml解析';9:00';as int

Python 3.x PyYaml解析';9:00';as int,python-3.x,yaml,pyyaml,Python 3.x,Yaml,Pyyaml,我有一个包含以下数据的文件: classes: - 9:00 - 10:20 - 12:10 (等至21:00) 我使用python3和yaml模块来解析它。确切地说,源代码是config=yaml.load(open(filename,'r'))。但是,当我打印配置时,我会得到这部分数据的以下输出: 'classes': [540, 630, 730, 820, 910, 1000, 1090, 1180], 列表中的值是整数 而之前,当我使用python2(和YAML的Bas

我有一个包含以下数据的文件:

classes:
  - 9:00
  - 10:20
  - 12:10
(等至21:00)

我使用python3和yaml模块来解析它。确切地说,源代码是
config=yaml.load(open(filename,'r'))
。但是,当我打印
配置
时,我会得到这部分数据的以下输出:

'classes': [540, 630, 730, 820, 910, 1000, 1090, 1180],
列表中的值是整数

而之前,当我使用python2(和YAML的
BaseLoader
)时,我得到了字符串形式的值,并将其作为字符串使用
BaseLoader
现在是不可接受的,因为我想从文件中读取unicode字符串,它会给我字节字符串

那么,首先,为什么pyyaml将我的数据解析为int


第二,我如何防止Pyaml这样做?是否可以在不更改数据文件的情况下执行此操作(例如,不添加
!!str

冒号用于映射值


我假定您想要的是字符串而不是整数,因此您应该双引号引字符串。

YAML的文档有点难以“解析”,因此我可以想象您忽略了关于冒号的这一点:

通常,YAML坚持将“:”映射值指示器与值用空格隔开。此限制的一个好处是“:”字符可以在普通标量中使用,只要后面没有空格。这允许不带引号的URL和时间戳。它也是一个潜在的混淆源,因为“a:1”是纯标量,而不是键:值对

你输入的是a,你的
9:00
被认为与9分零秒相似,总共相当于540秒

不幸的是,它并没有被构造成一些特殊的Sexagesimal实例,可以像计算整数一样用于计算,但可以以其原始形式打印出来。因此,如果要在内部将其用作字符串,则必须对其进行单引号:

classes:
  - '9:00'
  - '10:20'
  - '12:10'
如果您转储
{'classes':['9:00'、'10:20'、'12:10']}
(请注意,明确的
没有任何引号),您将得到这个结果

BaseLoader
为您提供字符串并不奇怪。
BaseLoader
使用的
BaseConstructor
任何标量处理为字符串,包括整数、布尔和“您的”六进制:

import ruamel.yaml as yaml

yaml_str = """\
classes:
  - 12345
  - 10:20
  - abc
  - True
"""

data = yaml.load(yaml_str, Loader=yaml.BaseLoader)
print(data)
data = yaml.load(yaml_str, Loader=yaml.SafeLoader)
给出:

{u'classes': [u'12345', u'10:20', u'abc', u'True']}
{'classes': [12345, 620, 'abc', True]}

如果确实不想使用引号,则必须“重置”以数字开头的标量的隐式解析器:

import ruamel.yaml as yaml
from ruamel.yaml.resolver import Resolver
import re

yaml_str = """\
classes:
  - 9:00
  - 10:20
  - 12:10
"""

for ch in list(u'-+0123456789'):
    del Resolver.yaml_implicit_resolvers[ch]
Resolver.add_implicit_resolver(
    u'tag:yaml.org,2002:int',
    re.compile(u'''^(?:[-+]?0b[0-1_]+
    |[-+]?0o?[0-7_]+
    |[-+]?(?:0|[1-9][0-9_]*)
    |[-+]?0x[0-9a-fA-F_]+)$''', re.X),  # <- copy from resolver.py without sexagesimal support
    list(u'-+0123456789'))

data = yaml.load(yaml_str, Loader=yaml.SafeLoader)
print(data)

此链接已在我的浏览器中标记为已访问:)我应该更仔细地阅读它。不过,现在在快速扫描yaml规范时,我并没有找到我的具体案例。无论如何,谢谢你的解决方案。
{'classes': ['9:00', '10:20', '12:10']}