YAML 在Python中的配置應用
YAML是一個堪比XML,JSON資料格式的更加方便,簡潔的,易於人眼閱讀的序列化資料格式。在很多的指令碼語言中都有涉及,下面以其在Python語言中為例,簡單的記錄一下,以備今後複習所用。
環境搭建
這貌似是所有試驗的開場白了,那就是搭建好本次試驗的環境。因為Python解析的時候,需要解析器的支援,所以需要安裝一個。
博主的為windows64位,所以選擇途中箭頭所示的版本。具體要依照個人情況而定。
安裝是否成功的驗證方法就是開啟Python直譯器,import一下即可。若出現下圖,那麼恭喜,環境搭建完畢了。
YAML語法
提及到語法層面,就得嚴肅認真一點了。之前看過阮一峰老師關於YAML在JavaScript中的應用,對比在Python中的應用,原理其實是一致的。可以參考一下:
語法規則
總的來說,語法沒什麼難度,也是人們司空見慣的了。
- 大小寫敏感
- 使用縮排表示層級關係
- 縮排時不允許使用Tab鍵,只允許使用空格。
- 縮排的空格數目不重要,只要相同層級的元素左側對齊即可
另外,和Python的註釋方式一樣,以#
號作為註釋符,很人性化了吧。
資料結構
YAML本身語法很簡單,但是卻可以基於此實現比較強大的配置功能。思考一下,作為一個配置檔案,可能出現的情況有哪些?
- 一連串型別一致的資料?
- 基本的資料型別?
key-value
組合?
其實,認真的思考一下就會明白了。YAML不是一個憑空捏造的資料格式,而是經過了實際考驗的人性化設計的一套規範。針對上面的問題,答案就是YAML本身支援的資料結構了,也很好記憶。
- 列表,陣列(一串型別相同或者不同的組合)
- 純量(類似於原子性,不可再分)
- 物件(鍵值對的組合,一對一的特性)
列表,陣列
類比Python語言,YAML性質與其保持一致。但是書寫方式上來說嘛,也可以是不一致的。大致有如下兩種:
[]
式:
['陣列1','陣列2','陣列3','陣列4','陣列5']
豎-
式:
- 陣列1
- 陣列2
- 陣列3
- 陣列4
- 陣列5
注意好符合一開始講的,語法規則即可。
原子量
也即是純量,不能再細分的資料結構。類比其他的程式語言,YAML也充分地考慮到了這一點。
數值型: 直接書寫即可。不區分整型還是浮點型。
-
- 單引號內會自動的轉義特殊字元,對單引號轉義是使用兩個單引號,其表示一個原生的單引號。
- 雙引號內保持原字元不變。
日期,時間:
- 時間: ISO8601 格式。如
2001-12-14t21:59:43.10-05:00
- 日期: 採用複合 iso8601 格式的年、月、日表示。如
1970-01-01
- 時間: ISO8601 格式。如
關於強制型別轉換: 可以通過兩個英文感嘆號+新的資料型別的方式來進行強制的型別轉換。
如:
e: !!str 123
f: !!str true
將變為:
{ e: '123', f: 'true' }
除此簡單的介紹之外,YAML還有很多更為奇妙的語法,但是掌握了這些基礎的使用,寫一個配置檔案基本上就夠用了。如果有興趣的話,可以在深入的研究一下。
YAML應用
這裡主要是記錄一下YAML在Python語言中的應用。類比於json庫,yaml庫與其有驚人的相似之處。一個load方法,一個dump方法。顧名知義,也比較的好理解。
案例
下面是從網上找的一個簡單的按照YAML語法書寫的一個檔案,將作為待會的源來使用。
name: Tom Smith
age: 37
spouse:
name: Jane Smith
age: 25
children:
- name: Jimmy Smith
age: 15
- name1: Jenny Smith
age1: 12
load
# coding:utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
# __author__ = '郭 璞'
# __date__ = '2016/10/31'
# __Desc__ = YAML 在Python中的應用
import yaml
stream = file('example.yaml', 'r')
data = yaml.load(stream)
print data['children'][0]['name']
所得結果為:
Jimmy Smith
理解層面以Python中的dict來理解即可。
dump
# coding:utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
# __author__ = '郭 璞'
# __date__ = '2016/10/31'
# __Desc__ = YAML 在Python中的應用
import yaml
s = 'I have an apple'
print yaml.dump(s)
lists = ['zhangsan', 'lisi', 'wangwu', 'zhaoliu']
print yaml.dump(lists)
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person('zhangsan', 19)
p2 = Person('lisi', 20)
p3 = Person('wangwu', 21)
persons = [p1, p2, p3]
print yaml.dump(persons)
執行結果:
I have an apple
...
[zhangsan, lisi, wangwu, zhaoliu]
- !!python/object:__main__.Person {age: 19, name: zhangsan}
- !!python/object:__main__.Person {age: 20, name: lisi}
- !!python/object:__main__.Person {age: 21, name: wangwu}
同樣的,這裡也可以看到強制型別轉換的身影。
總結
這樣的話,類比json庫的學習,yaml庫也可以很好的被應用了。
使用這樣的方式可以最大限度的解耦和程式碼,實現更高的可移植性。
同樣,寫配置檔案也不一定要用YAML,還可以有很多的選擇,比如ConfigParser
了, .ini
了,還可以自定義(藉助於正則表示式做好相關的存取即可)。
沒有哪種是最好的,只有適合的才是最好的。在不同的場合選擇適合自己的配置檔案的書寫方式即可。
(^__^) 嘻嘻……