YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一種标記語言)的遞歸縮寫,是一種人類易讀的資料序列化語言。它通常運用在一些資料代碼分離場合:用于配置檔案,但也用于資料存儲(例如調試輸出)或傳輸(例如文檔标題)。YAML 的配置檔案字尾為 .yml,如:runoob.yml 。
YAML支援的類型
-
對象
鍵值對的集合,又稱為映射(mapping)/ 哈希(hashes) / 字典(dictionary)
-
數組
一組按次序排列的值,又稱為序列(sequence) / 清單(list)
-
純量
單個的、不可再分的值
YAML的優點:
可讀性好;和腳本語言的互動性好;有一個一緻的資訊模型;易于實作;可以基于流來處理;表達能力強,擴充性好。
yaml的基本文法
1、大小寫敏感;
2、使用縮進表示層級關系,縮進隻可以使用空格,不允許使用tab,遵守左對齊即可;
3、清單中項通過“-”表示,字典中的通過“:”表示;
4、# 表示注釋,和python表示注釋一樣。
- 數值
number: 12.30
number2: 6.8523015e+5 #科學計數法表示
number3: 0b1010_0111_0100_1010_1110 #二進制表示
- 布爾值用
- null表示
- 日期時間
- 轉換資料類型。
int_to_str: !!str 123
bool_to_str: !!str true
一個比較完整的例子:
# 這是注釋
name: Joe
age: 18
languages:
- Python
websites:
YAML: yaml.org
Python: python.org
python操作
安裝
pip install pyyaml
加載
PyYAML加載YAMl檔案有8種方法:
load()
、
load_all()
、
safe_load()
safe_load_all()
、
unsafe_load()
、
unsafe_load_all()
、
full_load()
、
full_load_all()
。建議使用安全的safe_load()函數加載YAML檔案。
# coding:utf-8
import yaml
with open('test.yaml','r',encoding='utf-8') as f:
y = yaml.safe_load(f.read())
print(y)
結果
>>>{'name': 'J', 'age': 18, 'text': {'name': '軟體'}, 'skill': [{'name1': '測試'}, {'name2': '功能'}]}
關于PyYAML的load()方法的安全問題
PyYAML開發者明确知悉load()存在安全問題,但因為向前相容的問題沒有将load()改為預設以安全方式加載。建議在調用load()時必須以
Loader=
指定加載方式來緩解,是以沒有該參數情況下調用load()會産生警告。
在PyYAML 5.1+之前,load()可以輕松利用該函數來調用任何Python函數。這意味着它可以使用調用任何系統指令
os.system()
。這是一個簡單的示例:
pyyaml-5.3.1以後,仍然存在一些瑣碎的漏洞利用,不要在不受信任的資料上使用load,特别是FullLoader加載。
同時,PyYAML作者有意和Pickle序列化相容,會導緻不可信資料被不安全地加載。
- 除去警告
load時按需指定參數Loader即可:
加載器 | 描述 |
---|---|
BaseLoader | 僅加載最基本的YAML。所有标量都作為字元串加載。 |
SafeLoader | 安全地加載YAML語言的子集。建議用于加載不可信的輸入。 |
FullLoader | 加載完整的YAML語言。避免了一些執行代碼。 |
UnsafeLoader | 不受信任的輸入可能執行其他代碼。 |
後續FullLoader可能會棄用。
- 強制禁止警告
寫出
PyYAML寫出有四個函數:
dump()
、
dump_all()
、
safe_dump()
、
safe_dump_all()
,下面以safe_dump()為例:
import yaml
config = {'a': ['1', 'b']}
with open('test.yaml', 'w', encoding='utf8') as f:
yaml.safe_dump(config, f)