Python做接口测试读取yaml文件时,no变成了False,on变成了True,这是为什么?

我们先来写一个测试用的yaml文件

name: test yaml data
no: 1
file_path: /dir/test.yaml
data:
  on: PC
  is_long: yes

然后再来写一段python来读取这个yaml文件的内容

import yaml


def read_yaml():
    with open('./test.yaml', 'r', encoding='utf-8') as f:
        data = yaml.load(f, Loader=yaml.Loader)
    return data

调用read_yaml()方法,读取内容,打印出来,如下:

{
    "name":"test yaml data",
     False:1,
    "file_path":"/dir/test.yaml",
    "data":{
         True:"PC",
        "is_long":True
    }
}

对比原始的yaml文件可以看到

  • 值为1的字段名在原始文件是no,但是读取出来后是False
  • 值为PC的字段名在原始文件是on,但是读取出来后是True
  • 字段is_long的原始值为yes,但是读取出来后是True

可以发现,no变成了Falseonyes变成了True,好像触发了什么神秘代码,隐隐约约又像有点规律,这是为什么呢?

经过一番打断点的调试折腾,发现在yaml源码/site-packages/yaml/resolver.py里第170行有这么一段代码:

Resolver.add_implicit_resolver(
        'tag:yaml.org,2002:bool',
        re.compile(r'''^(?:yes|Yes|YES|no|No|NO
                    |true|True|TRUE|false|False|FALSE
                    |on|On|ON|off|Off|OFF)$''', re.X),
        list('yYnNtTfFoO'))

解析下就是,当正则匹配到yes|Yes|YES|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF等内容时,一律把这个内容当成一个bool类型的值,bool类型的值那就是True或者False

继续寻找,在/site-packages/yaml/constructor.py里第216行有这么一段代码:

bool_values = {
    'yes':      True,
    'no':       False,
    'true':     True,
    'false':    False,
    'on':       True,
    'off':      False,
}

这里定义了一个字典,字典里面的key分别对应了不同的bool

再观察下,发现这些key正是上面正则表达式里的内容,所以,这里的逻辑就是读取yaml文件时,会根据不同的内容给该内容一个标签,是列表或者字典或者字符串或者bool类型或者float型,判断属于哪种类型都是根据正则表达式来匹配的,而当匹配到

yes|Yes|YES|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF时,把他当做bool类型,又根据bool_values里面的定义,no就是Falseon就是Trueyes就是True,所以我们上面的yaml读取出来后,内容与原始文件不一样,原因就是如此。

再查阅一番,找到YAML官网关于bool的介绍,确实是这样,这些也正是yaml语言所规定的格式,可以理解为这些是yaml语言的内置关键字,类似于python里面的内置关键字,尽量的避免使用他们来作为内容。

如果确实需要用到这些特殊的名称,又不想让他变成bool类型,可以使用引号将其变为字符串,例如:

name: test yaml data
'no': 1
file_path: /dir/test.yaml
data:
  'on': PC
  is_long: 'yes'

这样再读取出来就没有问题了。

你可能感兴趣的:(Python做接口测试读取yaml文件时,no变成了False,on变成了True,这是为什么?)