YAML概要
1. 認識 YAML
YAML是一個類似 XML、JSON 的標記性語言。YAML 強調以數據為中心,並不是以標識語言為重點。因而 YAML 本身的定義比較簡單,號稱“一種人性化的數據格式語言”。
它的基本語法規則如下:
- 大小寫敏感
- 使用縮進表示層級關系
- 縮進時不允許使用Tab鍵,只允許使用空格。
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
1.1 YAML 的設計目標:
容易閱讀
可用於不同程序間的數據交換
適合描述程序所使用的數據結構,特別是腳本語言
豐富的表達能力與可擴展性
易於使用
1.2 YAML 與 XML、JSON
YAML 與 XML
具有 XML 同樣的優點,但比 XML 更加簡單、敏捷等
YAML 與 JSON
JSON 可以看作是 YAML 的子集,也就是說 JSON 能夠做的事情,YAML 也能夠做
YAML 能表示得比 JSON 更加簡單和閱讀,例如“字符串不需要引號”。所以 YAML 容易可以寫成 JSON 的格式,但並不建議這種做
YAML 能夠描述比 JSON 更加復雜的結構,例如“關系錨點”可以表示數據引用(如重復數據的引用)。
1.3 YAML 組織結構
YAML 文件可以由一或多個文檔組成(也即相對獨立的組織結構組成),文檔間使用“---”(三個橫線)在每文檔開始作為分隔符。同時,文檔也可以使用“...”(三個點號)作為結束符(可選)。如下圖所示:
如果只是單個文檔,分隔符“---”可省略。
每個文檔並不需要使用結束符“...”來表示結束,但是對於網絡傳輸或者流來說,作為明確結束的符號,有利於軟件處理。(例如不需要知道流關閉就能知道文檔結束)
文件讀取:
- 單個文件讀取load()
#test.yaml --- name: James age: 20
# -*- coding: utf-8 -*- import yaml
file_path = data/test.ymlfile = open(file_path, 'r', encoding='utf-8')
ys = yaml.load(file.read(), Loader=yaml.Loader)
print ys
輸出:{'age': 20, 'name': 'James'} - 將多個文檔寫在同一個yaml文件中,這時候我們就得用到我們的
load_all()
方法出場了,load_all()
方法會生成一個迭代器,可以用for輸出出來:#test.yaml --- name: James age: 20 --- name: Lily age: 19
# -*- coding: utf-8 -*- import yaml
file_path = data/test.yml
file = open(file_path, 'r', encoding='utf-8')
ys = yaml.load_all(file.read(), Loader=yaml.Loader)for y in ys:
print y
輸出: {'age': 20, 'name': 'James'} {'age': 19, 'name': 'Lily'}# -*- coding: utf-8 -*- import yaml file_path = data/test.yml file = open(file_path, 'r', encoding='utf-8') print(list(yaml.load_all(file.read(), Loader=yaml.Loader))) 輸出: [{'age': 20, 'name': 'James'}, ['Lily', 19]]
對應的也有
dump_all()
方法,一個意思,就是將多個段輸出到一個文件中,如:# -*- coding: utf-8 -*- import yaml obj1 = {"name": "James", "age": 20} obj2 = ["Lily", 19] with open('test.yaml', 'w') as f: yaml.dump_all([obj1, obj2], f)
打開test.yaml看看:
{age: 20, name: James} --- [Lily, 19]
dump()
和dump_all()
方法可以傳入列表,也可以傳入一個可序列化生成器,如range(10)
, 如下:# -*- coding: utf-8 -*- import yaml y = yaml.dump(range(10)) print y 輸出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
YAML 認為數據由以下三種結構組成:(每個文檔由三種結構混合組成)
標量 (相當於數據類型)
序列 (相當於數組和列表)
鍵值表(相當於 Map 表)
Yaml編寫規范
規范一:文檔使用 Unicode 編碼作為字符標准編碼,例如 UTF-8
規范二:使用“#”來表示注釋內容
# 客戶訂單 date: 2015-02-01 customer: - name: Jai items: - no: 1234 # 訂單號 - descript: cpu
規范三:使用空格作為嵌套縮進工具。通常建議使用兩個空格縮進,不建議使用 tab (甚至不支持)
規范四:序列表示
1、使用“-”(橫線) + 單個空格表示單個列表項
--- # 文檔開始 - 第一章 簡介 - 第二章 設計目錄
2、使用"[]"表示一組數據
--- # 文檔開始 [blue, red, green]
3、組合表示。每個結構都可以嵌套組成復雜的表示結構
--- # 文檔開始 - [blue, red, green] # 列表項本身也是一個列表 - [Age, Bag] - site: {osc:www.oschina.net, baidu: www.baidu.com} # 這里是同 鍵值表 組合表示
規范五:鍵值表
1、使用 “:”(冒號) + 空格表示單個鍵值對
# 客戶訂單 date: 2015-02-01 customer: - name: Jai items: - no: 1234 # 訂單號 - descript: cpu - price: ¥800.00
2、使用"{}"表示一個鍵值表
# 客戶訂單 date: 2015-02-01 customer: - name: Jai items: {no: 1234, descript: cpu, price: ¥800.00}
3、"? " 問號+空格表示復雜的鍵。當鍵是一個列表或鍵值表時,就需要使用本符號來標記
# 使用一個列表作為鍵 ? [blue, reg, green]: Color # 等價於 ? - blue - reg - gree : Color
4、組合表示。每個結構都可以嵌套組成復雜的表示結構
Color: - blue - red - green # 相當於 (也是 JSON 的表示) {Color: [blue, red, green]} div: - border: {color: red, width: 2px} - background: {color: green} - padding: [0, 10px, 0, 10px] # 使用縮進表示的鍵值表與列表項 items: - item: cpu model: i3 price: ¥800.00 - item: HD model: WD price: ¥450.00 # 上面使用 “-” 前導與縮進來表示多個列表項,相當於下面的JSON表示 items: [{item:cpu, model:i3, price:¥800.00}, {item:HD, model:WD, price: ¥450.00}]
規范六:文本塊
1、使用 “|” 和文本內容縮進表示的塊:保留塊中已有的回車換行。相當於段落塊
# 注意 ":" 與 "|" 之間的空格 yaml: | JSON的語法其實是YAML的子集,大部分的JSON文件都可以被YAML的解釋器解釋。 如果你想更深入的學習YAML,我建議你去 http://www.yaml.org 看看
2、使用 “>” 和文本內容縮進表示的塊:將塊中回車替換為空格,最終連接成一行
# 注意 ":" 與 ">" 之間的空格,另外可以使用空行來分段落 yaml: > JSON的語法其實是YAML的子集, 大部分的JSON文件都可以被YAML的解釋器解釋。 如果你想更深入的學習YAML,我建議你去 http://www.yaml.org 看看
3、使用定界符“”(雙引號)、‘’(單引號)或回車表示的塊:最終表示成一行
yaml: # 使用回車的多行,最終連接成一行。 JSON的語法其實是YAML的子集, 大部分的JSON文件都可以被YAML的解釋器解釋。 yaml: # 使用了雙引號,雙引號的好處是可以轉義,即在里面可以使用特殊符號 "JSON的語法其實是YAML的子集, 大部分的JSON文件都可以被YAML的解釋器解釋。"
4、當數據中含有空格或任意特殊字符,需要使用引號來包裹任何包含冒號的哈希值, 像這樣:
foo: "somebody said I should put a colon here: so I did" # 然后這個冒號將會被結尾.
規范七:數據類型的約定
1、對一些常用數據類型的表示格式進行了約定,包括:
integer: 12345 # 整數標准形式 octal: 0o34 # 八進制表示,第二個是字母 o hex: 0xFF # 十六進制表示 float: 1.23e+3 # 浮點數 fixed: 13.67 # 固定小數 minmin: -.inf # 表示負無窮 notNumber: .NaN # 無效數字 null: # 空值 boolean: [true, false] # 布爾值 string: ‘12345‘ # 字符串 date: 2015-08-23 # 日期 datetime: 2015-08-23T02:02:00.1z # 日期時間 iso8601: 2015-08-23t21:59:43.10-05:00 # iso8601 日期格式 spaced: 2015-08-23 21:59:43.10 -5 # ?
2、“!”(嘆號)顯式指示類型,或自定義類型標識。單嘆號通常是自定義類型,雙嘆號是內置類型,例如:
isString: !!str 2015-08-23 # 強調是字符串不是日期數據 picture: !!binary | # Base64 圖片 R0lGODlhDAAMAIQAAP//9/X 17unp5WZmZgAAAOfn515eXv Pz7Y6OjuDg4J+fn5OTk6enp 56enmleECcgggoBADs= #下面是內置類型 !!int # 整數類型 !!float # 浮點類型 !!bool # 布爾類型 !!str # 字符串類型 !!binary # 也是字符串類型 !!timestamp # 日期時間類型 !!null # 空值 !!set # 集合 !!omap, !!pairs # 鍵值列表或對象列表 !!seq # 序列,也是列表 !!map # 鍵值表 #下面是一些例子: --- !!omap - Mark: 65 - Sammy: 63 - Key: 58 --- !!set # 注意,“?”表示鍵為列表,在這里列表為 null ? Mark ? Sammy ? Key # 下面是自定義的類型或標識 %TAG ! tag:clarkevans.com,2002: # % 是指令符號 --- !shape # Use the ! handle for presenting # tag:clarkevans.com,2002:circle - !circle center: &ORIGIN {x: 73, y: 129} radius: 7 - !line start: *ORIGIN finish: { x: 89, y: 102 } - !label start: *ORIGIN color: 0xFFEEBB text: Pretty vector drawing.
#test.yaml(雙嘆號,強制轉換類型) str: !!str 3.14 int: !!int "123" 輸出:{'int': 123, 'str': '3.14'} #明顯能夠看出123被強轉成了int類型,而float型的3.14則被強轉成了str型
規范八:錨點與引用,定義數據的復用。
- 第一步:使用 “&” 定義數據錨點(即要復制的數據)
- 第二步:使用 “*” 引用上述錨點數據(即數據的復制目的地)
--- hr: - Mark McGwire # Following node labeled SS - &SS Sammy Sosa # 定義要復制的數據 rbi: - *SS # Subsequent occurrence 這里是數據復制目標 - Ken Griffey
原文1:https://blog.csdn.net/conquer0715/article/details/51283679
原文2:https://blog.csdn.net/lilun517735159/article/details/79230732