您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“怎么用Python實現解析yaml配置文件”,內容詳細,步驟清晰,細節處理妥當,希望這篇“怎么用Python實現解析yaml配置文件”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
yaml 文件以 .yml 結尾,在介紹它的語法結構之前我們先來看看 yaml 的一些基本規則。
大小寫敏感;
使用縮進表示層級關系,并且縮進只能用空格、不可以使用 tab 鍵。縮進的空格數目不重要,只要相同層級的元素左側對齊即可;
# 表示注釋,# 到行尾的所有字符都會被忽略;
yaml 支持的數據結構有以下三種:
字典:鍵值對的集合;
數組:多個元素組成的集合;
標量:單個、不可分割的值;
Python 解析 yaml 則是通過一個名為 pyyaml 的庫,直接 pip install pyyaml 即可。
下面我們來介紹一下 yaml 的數據結構。
類似于 Python 的字典,使用鍵值對表示:
name: satori # 或者寫成下面的形式 {name: satori}
Python 解析之后會是什么結果呢?
import yaml config = """ name: satori """ # yaml.safe_load:只解析自己信任的輸入 # yaml.unsafe_load:不檢測輸入的安全性 print(yaml.safe_load(config)) """ {'name': 'satori'} """ config = """ {name: satori} """ print(yaml.safe_load(config)) """ {'name': 'satori'} """
在 yaml 里面,字典的 value 也可以是一個字典:
info: {name: satori, address: 東方地靈殿}
Python 解析的結果如下:
import yaml config = """ info: {name: satori, address: 東方地靈殿} """ print(yaml.safe_load(config)) """ { 'info': {'name': 'satori', 'address': '東方地靈殿'} } """
還是很簡單的。
一組連字符開頭的行,構成一個數組。
- 古明地覺 - 古明地戀 - 霧雨魔理沙 # - 后面要有空格 # 或者寫成下面的形式 [古明地覺, 古明地戀, 霧雨魔理沙]
Python 解析的結果如下:
import yaml config = """ - 古明地覺 - 古明地戀 - 霧雨魔理沙 """ print(yaml.safe_load(config)) """ ['古明地覺', '古明地戀', '霧雨魔理沙'] """ config = """ [古明地覺, 古明地戀, 霧雨魔理沙] """ print(yaml.safe_load(config)) """ ['古明地覺', '古明地戀', '霧雨魔理沙'] """
并且數組的子成員也可以是一個數組:
-
- 古明地覺
- 古明地戀
- 霧雨魔理沙
Python 解析的結果如下:
import yaml config = """ - - 古明地覺 - 古明地戀 - 霧雨魔理沙 """ print(yaml.safe_load(config)) """ [['古明地覺', '古明地戀', '霧雨魔理沙']] """ # 更簡潔的寫法 config = """ - [古明地覺, 古明地戀, 霧雨魔理沙] """ print(yaml.safe_load(config)) """ [['古明地覺', '古明地戀', '霧雨魔理沙']] """
顯然數組也可以放在字典中:
# 縮進對應的空格數沒有要求,但是必須一樣 # 對于當前這個鍵值對而言也可以沒有縮進 girl: - 古明地覺 - 古明地戀 - 霧雨魔理沙 # 或者下面這種形式 girl: [古明地覺, 古明地戀, 霧雨魔理沙] # 或者下面這種形式 {girl: [古明地覺, 古明地戀, 霧雨魔理沙]}
Python 解析的結果如下:
import yaml config = """ girl: - 古明地覺 - 古明地戀 - 霧雨魔理沙 """ print(yaml.safe_load(config)) """ {'girl': ['古明地覺', '古明地戀', '霧雨魔理沙']} """ # 注意:上面的 girl 對應的是數組 # 因為每個元素前面都有 - # 但如果沒有的話會發生什么? config = """ girl: 古明地覺 古明地戀 霧雨魔理沙 """ print(yaml.safe_load(config)) """ {'girl': '古明地覺 古明地戀 霧雨魔理沙'} """ # 我們看到整體相當于是一個字符串 # 類似于 html,之間用一個空格代替 # 因此如果內容比較長,我們可以寫成多行 # 但是注意:每一行前面必須有空格
然后是一個稍微復雜的例子:
import yaml config = """ girl: # 會對應一個數組 - 古明地覺 - 古明地戀 - 霧雨魔理沙 place1: # 雖然不是數組,但是內部是字典的形式 # 所以會對應一個含有三個鍵值對的字典 古明地覺: 東方地靈殿 古明地戀: 東方地靈殿 霧雨魔理沙: 魔法森林 place2: # 是數組,數組里面每個元素是一個字典 - 古明地覺: 東方地靈殿 - 古明地戀: 東方地靈殿 - 霧雨魔理沙: 魔法森林 """ print(yaml.safe_load(config)) """ { 'girl': ['古明地覺', '古明地戀', '霧雨魔理沙'], 'place1': {'古明地覺': '東方地靈殿', '古明地戀': '東方地靈殿', '霧雨魔理沙': '魔法森林'}, 'place2': [{'古明地覺': '東方地靈殿'}, {'古明地戀': '東方地靈殿'}, {'霧雨魔理沙': '魔法森林'}] } """
place1 對應的是一個字典,place2 對應的是一個數組。
標量屬于最基本的、不可再分的值,比較簡單,我們就全部都說了吧。
import yaml config = """ int: 123 float: 3.14 bool: - true - false # 波浪號表示空 NoneType: ~ datetime: 2020-11-11 12:12:13 # 使用兩個 ! 可以進行類型強轉 # 不過幾乎用不到 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'] } """
這里可能有人已經發現了,就是字符串不需要加引號,但如果里面有特殊字符怎么辦?所以 yaml 是支持使用引號括起來的。
import yaml config = """ name1: 古明地覺 a x $ # !! name2: "古明地覺 a x $ # !!" name3: '古明地覺 a x $ # !!' """ print(yaml.safe_load(config)) """ {'name1': '古明地覺 a x $', 'name2': '古明地覺 a x $ # !!', 'name3': '古明地覺 a x $ # !!'} """
對于 yaml 而言,字符串默認是從第一個不是空格的字符、匹配到最后一個不是空格的字符(如果遇到 # 直接停止)。因此如果 value 的前面或后面有空格的話,那么這些空格是不會顯示的,或者當中有 #,那么 # 后面的內容也不會顯示。
解決辦法是使用單引號或雙引號括起來,如果內部還有引號,那么需要輸入兩遍進行轉義(如果內部的引號和外面括起來的引號相同的話)。
對于 yaml 而言,還支持我們采用 & 和 * 進行引用,舉個例子:
import yaml config = """ # 多了一個 &db_info_ref # 相當于起了個名字,叫 db_info_ref db_info: &db_info_ref host: 127.0.0.1 port: 5432 user: postgres password: 123456 deploy: os: Linux # 將內容直接扔到里面來 <<: *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'} } """
& 用來建立錨點,<< 表示合并當前數據,* 表示用來引用錨點。還可以作用在數組中:
import yaml config = """ - &name 古明地覺 - 古明地戀 - 霧雨魔理沙 - *name """ print(yaml.safe_load(config)) """ ['古明地覺', '古明地戀', '霧雨魔理沙', '古明地覺'] """
既然能夠讀取 yaml 文件,那么自然也能生成 yaml 文件。
import yaml data = { "girl": [ {"name": "古明地覺", "age": 17, "place": "東方地靈殿"}, {"name": "古明地戀", "age": 16, "place": "東方地靈殿"}, {"name": "霧雨魔理沙", "age": 16, "place": "魔法森林"} ], "other": { "古明地覺": {"nickname": ["小五", "少女覺", "覺大人", "小五蘿莉"], "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 文件長什么樣子。
我們來看 yml 文件,然后反推出相應的數據結構。首先整體是一個字典,里面有 girl 和 other 兩個 key。其中 girl 對應一個數組,數組里面每個元素都是字典,這是符合預期的。
然后 other 對應一個字典,而且這個字典內部有三個鍵值對,key 分別是:古明地覺、古明地戀、霧雨魔理沙,各自對應的 value 又是一個字典(內部有 length、nickname 兩個 key,length 對應整型、nickname 對應列表)。
最后再看一個本人之前項目中的 yml 文件,可以猜猜看解析出來長什么樣子。
解析一下看看和你想的是不是一樣的。
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'} } } """
結果應該不難想,畢竟 yaml 文件不是很復雜。
讀到這里,這篇“怎么用Python實現解析yaml配置文件”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。