使用 python 讀取 yaml 檔案

Yaml 全名是(YAML Ain’t a Markup Language)是一個可讀性高,用來表達資料序列的格式(更多資訊請參考 wiki).

之前要使用 Config 檔時,通常使用 Configparser 這個套件(Python wiki) ,他的config 檔格式長這樣:

[SectionOne]
Status: Single
Name: Derek
Value: Yes
Age: 30
Single: True

[SectionTwo]
FavoriteColor = Green
[SectionThree]
FamilyName: Johnson

[Others]
Route: 66

特色是可以用 section 來區分不同的設定檔內容,但是缺點是格式很單一,預設只能使用一對一的 Key-Value 的方式來建立,使用上少了一點彈性.

而 Yaml 的彈性就多多了,從 Python 的角度來看,Yaml 提供了以下種格式:

Dict: Dict 是最基本的格式,任何有“:” 的地方都會以 Dict 來呈現
resources:
cpu: .5
memory_gb: 1
disk_size_gb: 10

Parse 後:

‘resources’: {‘disk_size_gb’: 10, ‘cpu’: 0.5, ‘memory_gb’: 1}
List: 透過在每個選項前面加一個 “ — “ 號來實現
skip_files:
— ^(.*/)?#.*#$
— ^(.*/)?.*~$
— ^(.*/)?.*\.py[co]$
— ^(.*/)?.*/RCS/.*$
— ^(.*/)?\..*$

Parse 後:

'skip_files': [‘^(.*/)?#.*#$’, ‘^(.*/)?.*~$’, ‘^(.*/)?.*\\.py[co]$’, ‘^(.*/)?.*/RCS/.*$’, ‘^(.*/)?\\..*$’, ‘bin/’, ‘__pycache__/’, ‘lib/’, ‘include/’, ‘pip-selfcheck.json’]

細心的讀者應該有注意到,在 parse 過程中會自動辨識欄位屬性,例如 cpu 數就會被 parse 成 數值,而下方的 regular expression 就辨識成字串.

另外也可以儲存分行的文字:

test_block: |
first line
second line

parse 後,每個分行後會加上\n的分隔符號

‘test_block’: ‘first line\nsecond line\n’

另外一種分行文字

test_block1: >
first line
second line

parse 後,會變成同一行,以空白區隔

'test_block1': ‘first line second line\n’

讀取 Yaml 檔

python 內建 yaml package,使用方式也很簡單.

例如有個檔案長這樣:

runtime_config:
python_version: 3
env_variables:
SQLALCHEMY_DATABASE_URI: >-
mysql+mysqlconnector://qoo:123456@www.graffitalk.com
USER: ‘AAA BBB CCC DDD’
WORKPATH: /home/graffitalk/workspace
test_block: |
first line
second line
test_block1: >
first line
second line
resources:
cpu: .5
memory_gb: 1
disk_size_gb: 10
skip_files:
— ^(.*/)?#.*#$
— ^(.*/)?.*~$
— ^(.*/)?.*\.py[co]$
— ^(.*/)?.*/RCS/.*$
— ^(.*/)?\..*$
— bin/
— __pycache__/
— lib/
— include/
— pip-selfcheck.json

在 Python 中只要

import yaml
with open(“app.yaml”, “r”) as stream:
data = yaml.load(stream)

data 會以 dictionary 的方式呈現:

{‘resources’: {‘disk_size_gb’: 10, ‘cpu’: 0.5, ‘memory_gb’: 1}, ‘test_block’: ‘first line\nsecond line\n’, ‘runtime_config’: {‘python_version’: 3}, ‘env_variables’: {‘USER’: ‘AAA BBB CCC DDD’, ‘WORKPATH’: ‘/home/graffitalk/workspace’, ‘SQLALCHEMY_DATABASE_URI’: ‘mysql+mysqlconnector://qoo:123456@www.graffitalk.com'}, ‘test_block1’: ‘first line second line\n’, ‘env’: ‘flex’, ‘skip_files’: [‘^(.*/)?#.*#$’, ‘^(.*/)?.*~$’, ‘^(.*/)?.*\\.py[co]$’, ‘^(.*/)?.*/RCS/.*$’, ‘^(.*/)?\\..*$’, ‘bin/’, ‘__pycache__/’, ‘lib/’, ‘include/’, ‘pip-selfcheck.json’], ‘service’: ‘default’, ‘entrypoint’: ‘python app.py’, ‘runtime’: ‘python’}