Python做接口測(cè)試讀取yaml文件時(shí),no變成了False,on變成了True,這是為什么?

我們先來(lái)寫一個(gè)測(cè)試用的yaml文件

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

然后再來(lái)寫一段python來(lái)讀取這個(gè)yaml文件的內(nèi)容

import yaml


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

調(diào)用read_yaml()方法,讀取內(nèi)容,打印出來(lái),如下:

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

對(duì)比原始的yaml文件可以看到

  • 值為1的字段名在原始文件是no,但是讀取出來(lái)后是False
  • 值為PC的字段名在原始文件是on,但是讀取出來(lái)后是True
  • 字段is_long的原始值為yes,但是讀取出來(lái)后是True

可以發(fā)現(xiàn),no變成了False,onyes變成了True,好像觸發(fā)了什么神秘代碼,隱隱約約又像有點(diǎn)規(guī)律,這是為什么呢?

經(jīng)過(guò)一番打斷點(diǎn)的調(diào)試折騰,發(fā)現(xiàn)在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'))

解析下就是,當(dāng)正則匹配到yes|Yes|YES|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF等內(nèi)容時(shí),一律把這個(gè)內(nèi)容當(dāng)成一個(gè)bool類型的值,bool類型的值那就是True或者False

繼續(xù)尋找,在/site-packages/yaml/constructor.py里第216行有這么一段代碼:

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

這里定義了一個(gè)字典,字典里面的key分別對(duì)應(yīng)了不同的bool

再觀察下,發(fā)現(xiàn)這些key正是上面正則表達(dá)式里的內(nèi)容,所以,這里的邏輯就是讀取yaml文件時(shí),會(huì)根據(jù)不同的內(nèi)容給該內(nèi)容一個(gè)標(biāo)簽,是列表或者字典或者字符串或者bool類型或者float型,判斷屬于哪種類型都是根據(jù)正則表達(dá)式來(lái)匹配的,而當(dāng)匹配到

yes|Yes|YES|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF時(shí),把他當(dāng)做bool類型,又根據(jù)bool_values里面的定義,no就是False,on就是Trueyes就是True,所以我們上面的yaml讀取出來(lái)后,內(nèi)容與原始文件不一樣,原因就是如此。

再查閱一番,找到YAML官網(wǎng)關(guān)于bool的介紹,確實(shí)是這樣,這些也正是yaml語(yǔ)言所規(guī)定的格式,可以理解為這些是yaml語(yǔ)言的內(nèi)置關(guān)鍵字,類似于python里面的內(nèi)置關(guān)鍵字,盡量的避免使用他們來(lái)作為內(nèi)容。

如果確實(shí)需要用到這些特殊的名稱,又不想讓他變成bool類型,可以使用引號(hào)將其變?yōu)樽址纾?/p>

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

這樣再讀取出來(lái)就沒(méi)有問(wèn)題了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容