天天看點

YAML簡介和PyYAML安全操作YAML支援的類型YAML的優點:yaml的基本文法python操作

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)