欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python實(shí)現(xiàn)解析yaml配置文件的示例詳解

 更新時(shí)間:2022年09月18日 08:16:04   作者:古明地覺(jué)  
在開發(fā)過(guò)程中,配置文件是少不了的,而且配置文件是有專門的格式的,比如:ini,yaml,toml等等。本文帶大家來(lái)看看Python如何解析yaml文件,它的表達(dá)能力相比?ini?更加的強(qiáng)大,需要的可以參考一下

楔子

前面我們介紹了 ini 格式的配置文件,本次來(lái)看看 yaml,它的表達(dá)能力相比 ini 更加的強(qiáng)大。yaml 文件以 .yml 結(jié)尾,在介紹它的語(yǔ)法結(jié)構(gòu)之前我們先來(lái)看看 yaml 的一些基本規(guī)則。

  • 大小寫敏感;
  • 使用縮進(jìn)表示層級(jí)關(guān)系,并且縮進(jìn)只能用空格、不可以使用 tab 鍵??s進(jìn)的空格數(shù)目不重要,只要相同層級(jí)的元素左側(cè)對(duì)齊即可;
  • # 表示注釋,# 到行尾的所有字符都會(huì)被忽略;

yaml 支持的數(shù)據(jù)結(jié)構(gòu)有以下三種:

  • 字典:鍵值對(duì)的集合;
  • 數(shù)組:多個(gè)元素組成的集合;
  • 標(biāo)量:?jiǎn)蝹€(gè)、不可分割的值;

Python 解析 yaml 則是通過(guò)一個(gè)名為 pyyaml 的庫(kù),直接 pip install pyyaml 即可。

下面我們來(lái)介紹一下 yaml 的數(shù)據(jù)結(jié)構(gòu)。

字典

類似于 Python 的字典,使用鍵值對(duì)表示:

name:?satori
#?或者寫成下面的形式
{name:?satori}

Python 解析之后會(huì)是什么結(jié)果呢?

import?yaml

config?=?"""
name:?satori
"""

# yaml.safe_load:只解析自己信任的輸入
# yaml.unsafe_load:不檢測(cè)輸入的安全性
print(yaml.safe_load(config))
"""
{'name':?'satori'}
"""

config?=?"""
{name:?satori}
"""
print(yaml.safe_load(config))
"""
{'name':?'satori'}
"""

在 yaml 里面,字典的 value 也可以是一個(gè)字典:

info:?{name:?satori,?address:?東方地靈殿}

Python 解析的結(jié)果如下:

import?yaml

config?=?"""
info:?{name:?satori,?address:?東方地靈殿}
"""

print(yaml.safe_load(config))
"""
{
??'info':?{'name':?'satori',?
???????????'address':?'東方地靈殿'}
}
"""

還是很簡(jiǎn)單的。

數(shù)組

一組連字符開頭的行,構(gòu)成一個(gè)數(shù)組。

-?古明地覺(jué)
-?古明地戀
-?霧雨魔理沙
#?-?后面要有空格
#?或者寫成下面的形式
[古明地覺(jué),?古明地戀,?霧雨魔理沙]

Python 解析的結(jié)果如下:

import?yaml

config?=?"""
-?古明地覺(jué)
-?古明地戀
-?霧雨魔理沙
"""

print(yaml.safe_load(config))
"""
['古明地覺(jué)',?'古明地戀',?'霧雨魔理沙']
"""

config?=?"""
[古明地覺(jué),?古明地戀,?霧雨魔理沙]
"""

print(yaml.safe_load(config))
"""
['古明地覺(jué)',?'古明地戀',?'霧雨魔理沙']
"""

并且數(shù)組的子成員也可以是一個(gè)數(shù)組:

-
 - 古明地覺(jué)
 - 古明地戀
 - 霧雨魔理沙

Python 解析的結(jié)果如下:

import?yaml

config?=?"""
-
??-?古明地覺(jué)
??-?古明地戀
??-?霧雨魔理沙
"""

print(yaml.safe_load(config))
"""
[['古明地覺(jué)',?'古明地戀',?'霧雨魔理沙']]
"""

#?更簡(jiǎn)潔的寫法
config?=?"""
-?[古明地覺(jué),?古明地戀,?霧雨魔理沙]
"""

print(yaml.safe_load(config))
"""
[['古明地覺(jué)',?'古明地戀',?'霧雨魔理沙']]
"""

顯然數(shù)組也可以放在字典中:

#?縮進(jìn)對(duì)應(yīng)的空格數(shù)沒(méi)有要求,但是必須一樣
#?對(duì)于當(dāng)前這個(gè)鍵值對(duì)而言也可以沒(méi)有縮進(jìn)
girl:
????-?古明地覺(jué)
????-?古明地戀
????-?霧雨魔理沙
#?或者下面這種形式
girl:?[古明地覺(jué),?古明地戀,?霧雨魔理沙]
#?或者下面這種形式
{girl:?[古明地覺(jué),?古明地戀,?霧雨魔理沙]}

Python 解析的結(jié)果如下:

import?yaml

config?=?"""
girl:
??-?古明地覺(jué)
??-?古明地戀
??-?霧雨魔理沙
"""

print(yaml.safe_load(config))
"""
{'girl':?['古明地覺(jué)',?'古明地戀',?'霧雨魔理沙']}
"""

#?注意:上面的 girl 對(duì)應(yīng)的是數(shù)組
#?因?yàn)槊總€(gè)元素前面都有?-
#?但如果沒(méi)有的話會(huì)發(fā)生什么?
config?=?"""
girl:
????古明地覺(jué)
????古明地戀
????霧雨魔理沙
"""

print(yaml.safe_load(config))
"""
{'girl':?'古明地覺(jué)?古明地戀?霧雨魔理沙'}
"""
#?我們看到整體相當(dāng)于是一個(gè)字符串
#?類似于?html,之間用一個(gè)空格代替
#?因此如果內(nèi)容比較長(zhǎng),我們可以寫成多行
#?但是注意:每一行前面必須有空格

然后是一個(gè)稍微復(fù)雜的例子:

import?yaml

config?=?"""
girl:
????#?會(huì)對(duì)應(yīng)一個(gè)數(shù)組
????-?古明地覺(jué)
????-?古明地戀
????-?霧雨魔理沙
????
place1:
????#?雖然不是數(shù)組,但是內(nèi)部是字典的形式
????#?所以會(huì)對(duì)應(yīng)一個(gè)含有三個(gè)鍵值對(duì)的字典
????古明地覺(jué):?東方地靈殿
????古明地戀:?東方地靈殿
????霧雨魔理沙:?魔法森林

place2:
??#?是數(shù)組,數(shù)組里面每個(gè)元素是一個(gè)字典
??-?古明地覺(jué):?東方地靈殿
??-?古明地戀:?東方地靈殿
??-?霧雨魔理沙:?魔法森林
"""

print(yaml.safe_load(config))
"""
{
????'girl':?['古明地覺(jué)',?'古明地戀',?'霧雨魔理沙'],
????'place1':?{'古明地覺(jué)':?'東方地靈殿',?
???????????????'古明地戀':?'東方地靈殿',?
???????????????'霧雨魔理沙':?'魔法森林'},
????'place2':?[{'古明地覺(jué)':?'東方地靈殿'},?
???????????????{'古明地戀':?'東方地靈殿'},?
???????????????{'霧雨魔理沙':?'魔法森林'}]
}
"""

place1 對(duì)應(yīng)的是一個(gè)字典,place2 對(duì)應(yīng)的是一個(gè)數(shù)組。

標(biāo)量

標(biāo)量屬于最基本的、不可再分的值,比較簡(jiǎn)單,我們就全部都說(shuō)了吧。

import?yaml

config?=?"""
int:?123
float:?3.14
bool:
????-?true?
????-?false
#?波浪號(hào)表示空????
NoneType:?~??
datetime:?2020-11-11?12:12:13

#?使用兩個(gè)?!?可以進(jìn)行類型強(qiáng)轉(zhuǎn)
#?不過(guò)幾乎用不到?
cast:
????-?!!str?123
????-?!!str?true??
"""

print(yaml.safe_load(config))
"""
{
????'int':?123,?'float':?3.14,
????'bool':?[True,?False],?'NoneType':?None,
????'datetime':?datetime.datetime(2020,?11,?11,?12,?12,?13),?
????'cast':?['123',?'true']
}
"""

這里可能有人已經(jīng)發(fā)現(xiàn)了,就是字符串不需要加引號(hào),但如果里面有特殊字符怎么辦?所以 yaml 是支持使用引號(hào)括起來(lái)的。

import?yaml

config?=?"""
name1:?古明地覺(jué)??????a?x???$?#??!!????????
name2:?"古明地覺(jué)??????a?x???$?#??!!"????????
name3:?'古明地覺(jué)??????a?x???$?#??!!'???
"""

print(yaml.safe_load(config))
"""
{'name1':?'古明地覺(jué)??????a?x???$',?
?'name2':?'古明地覺(jué)??????a?x???$?#??!!',?
?'name3':?'古明地覺(jué)??????a?x???$?#??!!'}
"""

對(duì)于 yaml 而言,字符串默認(rèn)是從第一個(gè)不是空格的字符、匹配到最后一個(gè)不是空格的字符(如果遇到 # 直接停止)。因此如果 value 的前面或后面有空格的話,那么這些空格是不會(huì)顯示的,或者當(dāng)中有 #,那么 # 后面的內(nèi)容也不會(huì)顯示。

解決辦法是使用單引號(hào)或雙引號(hào)括起來(lái),如果內(nèi)部還有引號(hào),那么需要輸入兩遍進(jìn)行轉(zhuǎn)義(如果內(nèi)部的引號(hào)和外面括起來(lái)的引號(hào)相同的話)。

引用

對(duì)于 yaml 而言,還支持我們采用 & 和 * 進(jìn)行引用,舉個(gè)例子:

import?yaml

config?=?"""
#?多了一個(gè)?&db_info_ref
#?相當(dāng)于起了個(gè)名字,叫?db_info_ref
db_info:?&db_info_ref??
????host:?127.0.0.1
????port:?5432
????user:?postgres
????password:?123456

deploy:
????os:?Linux
????#?將內(nèi)容直接扔到里面來(lái)??
????<<:?*db_info_ref??
"""

print(yaml.safe_load(config))
"""
{
????'db_info':?{'host':?'127.0.0.1',
????????????????'port':?5432,
????????????????'user':?'postgres',
????????????????'password':?123456},
????'deploy':?{'host':?'127.0.0.1',
???????????????'port':?5432,
???????????????'user':?'postgres',
???????????????'password':?123456,
???????????????'os':?'Linux'}
}
"""

& 用來(lái)建立錨點(diǎn),<< 表示合并當(dāng)前數(shù)據(jù),* 表示用來(lái)引用錨點(diǎn)。還可以作用在數(shù)組中:

import?yaml

config?=?"""
-?&name?古明地覺(jué)?
-?古明地戀
-?霧雨魔理沙
-?*name
"""

print(yaml.safe_load(config))
"""
['古明地覺(jué)',?'古明地戀',?
?'霧雨魔理沙',?'古明地覺(jué)']
"""

生成 yaml 文件

既然能夠讀取 yaml 文件,那么自然也能生成 yaml 文件。

import?yaml

data?=?{
????"girl":?[
????????{"name":?"古明地覺(jué)",?"age":?17,?"place":?"東方地靈殿"},
????????{"name":?"古明地戀",?"age":?16,?"place":?"東方地靈殿"},
????????{"name":?"霧雨魔理沙",?"age":?16,?"place":?"魔法森林"}
????],
????"other":?{
????????"古明地覺(jué)":?{"nickname":?["小五",?"少女覺(jué)",?"覺(jué)大人",?"小五蘿莉"],
?????????????????"length":?155},
????????"古明地戀":?{"nickname":?["戀戀"],?"length":?155},
????????"霧雨魔理沙":?{"nickname":?["摸你傻"],?"length":?155}
????}
}

with?open("cfg.yml",?"w",?encoding="utf-8")?as?f:
????yaml.dump(data,?f,?allow_unicode=True,?indent=2)

然后我們看看生成的 yml 文件長(zhǎng)什么樣子。

我們來(lái)看 yml 文件,然后反推出相應(yīng)的數(shù)據(jù)結(jié)構(gòu)。首先整體是一個(gè)字典,里面有 girl 和 other 兩個(gè) key。其中 girl 對(duì)應(yīng)一個(gè)數(shù)組,數(shù)組里面每個(gè)元素都是字典,這是符合預(yù)期的。

然后 other 對(duì)應(yīng)一個(gè)字典,而且這個(gè)字典內(nèi)部有三個(gè)鍵值對(duì),key 分別是:古明地覺(jué)、古明地戀、霧雨魔理沙,各自對(duì)應(yīng)的 value 又是一個(gè)字典(內(nèi)部有 length、nickname 兩個(gè) key,length 對(duì)應(yīng)整型、nickname 對(duì)應(yīng)列表)。

最后再看一個(gè)本人之前項(xiàng)目中的 yml 文件,可以猜猜看解析出來(lái)長(zhǎng)什么樣子。

解析一下看看和你想的是不是一樣的。

import?yaml

with?open(".gitlab-ci.yml",?"r",?encoding="utf-8")?as?f:
????data?=?f.read()

data?=?yaml.safe_load(data)
print(data)
"""
{
????'stages':?['test'],?
????'cache':?{'key':?'${CI_COMMIT_REF_SLUG}',?
??????????????'paths':?['.cache/pip']},
????'variables':?{'PIP_CACHE_DIR':?'$CI_PROJECT_DIR/.cache/pip'},
????'test':?{'stage':?'test',?
?????????????'image':?'xxxxxxx/python:3.8.1-thanosclient-buster',?
?????????????'only':?['branches',?'tags'],
?????????????'services':?['mysql:5.7'],
?????????????'variables':?{'PROJECT':?'XXXXXX',?
???????????????????????????'PIP_CACHE_DIR':?'$CI_PROJECT_DIR/.cache/pip',
???????????????????????????'MARKETING_CONFIG':?'config/room/ci.cn-gz.toml',
???????????????????????????'MYSQL_DATABASE':?'activity',?
???????????????????????????'MYSQL_ROOT_PASSWORD':?'password',
???????????????????????????'MYSQL_INITDB_SKIP_TZINFO':?'1'}
?????????????}
}
"""

結(jié)果應(yīng)該不難想,畢竟 yaml 文件不是很復(fù)雜。

以上就是Python實(shí)現(xiàn)解析yaml配置文件的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Python解析yaml配置文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論