JB的Python之旅-yaml介紹

jb發表於2018-06-25

前言

在用gitlab ci的時候,會用到yml檔案配置,但是yml到底是啥?一點印象都沒有,所以想學習瞭解下~

目的

學習yaml語法,以及在python裡面怎麼使用

yaml

yaml這個詞是JB第一次接觸,就是在折騰gitlab ci時,需要處理.gitlab-ci.yml檔案,從而接觸到yaml;
一開始以為是類php的玩意,結果發現有些寫法對不上,那導致,什麼是yaml?它是幹嘛的?

官網連結:http://yaml.org/

官網裡面有句話:

JB的Python之旅-yaml介紹
不是標記語言,是表達資料序列語言;
換個角度看,YAML 是專門用來寫配置檔案的語言
據說非常簡潔和強大,遠比 JSON、xml等 格式方便。

簡介

YAML 語言設計目標,就是方便人類讀寫;
它實質上是一種通用的資料序列化格式;
以資料為中心,使用空白,縮排,分行組織資料,從而使得表示更加簡潔易讀;
它的基本語法規則如下:

  • 大小寫敏感
  • 使用縮排表示層級關係
  • 縮排時不允許使用Tab鍵,只允許使用空格。
  • 縮排的空格數目不重要,只要相同層級的元素左側對齊即可
  • 使用#表示註釋,從這個字元一直到行尾,都會被解析器忽略。
  • 字串可以不用引號標註

三種資料結構

1)物件
鍵值對的集合,又稱為對映(mapping)/ 雜湊(hashes) / 字典(dictionary)
使用冒號(:)表示鍵值對,同一縮排的所有鍵值對屬於一個map

# YAML表示
age : 18
name : jb

或者寫成一行:
# YAML表示
{age:12,name:huang}

# 對應的Json表示
{'age':18,'name':'jb'}
複製程式碼

2)list,陣列
一組連詞線(-)開頭的行,構成一個陣列

# YAML表示
- a
- b
- 12

或者寫成一行:
# YAML表示
[a,b,c]

# 對應Json表示
['a','b',12]
複製程式碼

3)scalar,純量
資料最小的單位,不可以再分割
比如數值型,字串,日期,字串等;

資料結構巢狀

1)map巢狀map

# YAML表示
websites:
 YAML: yaml.org 
 Ruby: ruby-lang.org 
 Python: python.org 
 Perl: use.perl.org 

# 對應Json表示
{ websites: 
   { YAML: 'yaml.org',
     Ruby: 'ruby-lang.org',
     Python: 'python.org',
     Perl: 'use.perl.org' } }
複製程式碼

2)map巢狀list

# YAML表示
languages:
 - Ruby
 - Perl
 - Python 
 - c

# 對應Json表示
{ languages: [ 'Ruby', 'Perl', 'Python', 'c' ] }
複製程式碼

3)list巢狀list

# YAML表示
-
  - Ruby
  - Perl
  - Python 
- 
  - c
  - c++
  - java

# 對應Json表示
[ [ 'Ruby', 'Perl', 'Python' ], [ 'c', 'c++', 'java' ] ]
複製程式碼

除此之外,還可以下面這樣顯示:

# 方法2
- - Ruby
  - Perl
  - Python 
- - c
  - c++
  - java

# 方法3
- [Ruby,Perl,Python]
- [c,c++,java]
複製程式碼

4)list巢狀map

# YAML表示
-
  id: 1
  name: huang
-
  id: 2
  name: liao

# 對應Json表示
[ { id: 1, name: 'huang' }, { id: 2, name: 'liao' } ]
複製程式碼

安裝yaml模組

pip install pyyaml
複製程式碼

編寫yaml檔案

安裝成功後,那就手動新建一個yaml檔案吧:

name: jb
age: 18
spouse:
    name: jb2
    age: 19
children:
    - name: jb3
      age: 1
    - name: jb4
      age: 2
複製程式碼

如果要修改其中的內容,怎麼處理?看個例子就明白了;

import yaml

f = open("jb.yaml")
content = yaml.load(f)
#上面2步時讀取yml檔案

print("修改前:"+str(content))
content["age"] = 17
content["children"][1]["age"] = 18
print("修改後:"+str(content))

執行的結果:
修改前:{'name': 'jb', 'age': 18, 'spouse': {'name': 'jb2', 'age': 19}, 'children': [{'name': 'jb3', 'age': 1}, {'name': 'jb4', 'age': 2}]}
修改後:{'name': 'jb', 'age': 17, 'spouse': {'name': 'jb2', 'age': 19}, 'children': [{'name': 'jb3', 'age': 1}, {'name': 'jb4', 'age': 18}]}
複製程式碼

這裡面介紹了load方法,返回一個物件;

那如果有幾塊yaml文件,可以用load_all()處理,生成的時一個迭代器:

資料修改成:

name: jb
---
age: 18
spouse:
    name: jb2
    age: 19
children:
    - name: jb3
      age: 1
    - name: jb4
      age: 2
      
      
程式碼如下:
import yaml

f = open("jb.yaml")
content = yaml.load_all(f)

for i in content:
    print(i)

輸出的結果:
'name': 'jb'}
{'age': 18, 'spouse': {'name': 'jb2', 'age': 19}, 'children': [{'name': 'jb3', 'age': 1}, {'name': 'jb4', 'age': 2}]}
複製程式碼

dump,將一個python物件生成為yaml文件

import yaml
aproject = {'name': 'jb',
            'race': 'jb',
            'traits': ['ONE_HAND', 'ONE_EYE']
            }

print(yaml.dump(aproject,))

執行的結果:
name: jb
race: jb
traits: [ONE_HAND, ONE_EYE]
複製程式碼

dump接收的第二個引數一定要是一個開啟的文字檔案或二進位制檔案,
yaml.dump會把生成的yaml文件寫到檔案裡

import yaml

aproject = {'name': 'jb',
            'race': 'jb',
            'traits': ['ONE_HAND', 'ONE_EYE']
            }
f = open(r'C:\Users\jb\gitprojects\jbtest\jb.yaml','w')
print(yaml.dump(aproject,f))
複製程式碼

這樣就能把所需要的內容落地到檔案~

JB的Python之旅-yaml介紹

dump_all,將多個段輸出到要給檔案中
上面的例子是一個段,如果有多個段,要怎麼落地檔案呢?
這時候,就可以用dump_all了;

import yaml

obj1 = {"name": "jb", "age": 2}
obj2 = ["jb2", 3]

f = open(r'C:\Users\jb\gitprojects\jbtest\jb.yaml','w')
print(yaml.dump([obj1,obj2],f))
複製程式碼

輸出的結果:

JB的Python之旅-yaml介紹

yaml、xml、json

關於yaml基本用法就這幾個,不打算再深入瞭解,只想起到掃盲效果即可;

換個話題,yaml的介紹是說,比xml跟json都好用,那我們一起看看,怎麼好用~
1)yaml跟xml
以下為同一內容,分別用xml跟yaml表示

# xml標記兩個site
<site>
    <name>sina</name>
    <url>http://www.361way.com</url>
</site>
<site>
    <name>google</name>
    <url>http://www.91it.org</url>
</site>
# 使用yaml標記兩個site
---
site:
    name: sina
    url : http://www.361way.com
---
site:
    name: google
    url : http://www.91it.org
# 使用yaml標記兩個site
---
site: {name: sina, url: http://www.361way.com}
---
site: {name: google, url: http://www.91it.org}
複製程式碼

從檢視資訊的角度,yaml感覺直觀多了~

2)yaml跟json
yaml跟json是非常相似的,並沒有xml那樣可以只管看出,而python提供方法在兩者之間轉換;

yaml到json

import yaml,json
yml = """
---
  foo: bar
"""
data = yaml.load(yml)
json = json.dumps(data)
print(json)
複製程式碼

輸出的結果:

{"foo": "bar"}
複製程式碼

json轉yaml:

import json,yaml
str = '{ "foo": "bar" }'
data = json.loads(str)
yml = yaml.safe_dump(data)
print(yml)
複製程式碼

輸出的結果:

{foo: bar}
複製程式碼

其實json跟yaml的差別不是很大的~

小結

本文主要介紹了yaml是什麼東東,並且與xml的區別,介紹了load、load_all、dump、duml_all方法的使用,大致就這樣吧,掃盲專用~

謝謝大家~

JB的Python之旅-yaml介紹

相關文章