我們先來(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,on和yes變成了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就是True,yes就是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)題了。