1. 程式人生 > >YAML 在Python中的配置應用

YAML 在Python中的配置應用

YAML是一個堪比XML,JSON資料格式的更加方便,簡潔的,易於人眼閱讀的序列化資料格式。在很多的指令碼語言中都有涉及,下面以其在Python語言中為例,簡單的記錄一下,以備今後複習所用。

環境搭建

這貌似是所有試驗的開場白了,那就是搭建好本次試驗的環境。因為Python解析的時候,需要解析器的支援,所以需要安裝一個。

博主的為windows64位,所以選擇途中箭頭所示的版本。具體要依照個人情況而定。

安裝是否成功的驗證方法就是開啟Python直譯器,import一下即可。若出現下圖,那麼恭喜,環境搭建完畢了。
驗證yaml環境是否安裝成功

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
  • 關於強制型別轉換: 可以通過兩個英文感嘆號+新的資料型別的方式來進行強制的型別轉換。

如:

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了,還可以自定義(藉助於正則表示式做好相關的存取即可)。

沒有哪種是最好的,只有適合的才是最好的。在不同的場合選擇適合自己的配置檔案的書寫方式即可。

(^__^) 嘻嘻……