python如何操作yaml方法講解-創(chuàng)新互聯(lián)

本篇內(nèi)容介紹了“python如何操作yaml方法講解”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

成都創(chuàng)新互聯(lián)是一家專注于成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),霞山網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:霞山等地區(qū)。霞山做網(wǎng)站價(jià)格咨詢:18982081108

1. 安裝PyYAML

pip install PyYAML

2. 加載yaml文件

直接使用yaml.load()函數(shù)

demo.yml :

kind: Deployment
apiVersion: apps/v1
metadata:
 name: podinfo
 namespace: yaml-demo
spec:
 replicas: 1
 selector:
  matchLabels:
   app: podinfo
 template:
  metadata:
   labels:
    app: podinfo
  spec:
   containers:
   - name: podinfod
    image: quay.io/stefanprodan/podinfo:0.3.0
    ports:
    - containerPort: 9898

load.py :

import yaml
import json

result = yaml.load(open('demo.yml'))
print json.dumps(result, indent=2)

輸出 :

{
 "kind": "Deployment",
 "spec": {
  "replicas": 1,
  "template": {
   "spec": {
    "containers": [
     {
      "image": "quay.io/stefanprodan/podinfo:0.3.0",
      "name": "podinfod",
      "ports": [
       {
        "containerPort": 9898
       }
      ]
     }
    ]
   },
   "metadata": {
    "labels": {
     "app": "podinfo"
    }
   }
  },
  "selector": {
   "matchLabels": {
    "app": "podinfo"
   }
  }
 },
 "apiVersion": "apps/v1",
 "metadata": {
  "namespace": "yaml-demo",
  "name": "podinfo"
 }
}

3. 持久化dict到y(tǒng)ml文件

使用yaml.safe_dump()函數(shù)

dump.py :

import yaml

d = {
 "kind": "Deployment",
 "spec": {
  "replicas": 1,
  "template": {
   "spec": {
    "containers": [
     {
      "image": "quay.io/stefanprodan/podinfo:0.3.0",
      "name": "podinfod",
      "ports": [
       {
        "containerPort": 9898
       }
      ]
     }
    ]
   },
   "metadata": {
    "labels": {
     "app": "podinfo"
    }
   }
  },
  "selector": {
   "matchLabels": {
    "app": "podinfo"
   }
  }
 },
 "apiVersion": "apps/v1",
 "metadata": {
  "namespace": "yaml-demo",
  "name": "podinfo"
 }
}
result = yaml.safe_dump(d, encoding='utf-8', allow_unicode=True, default_flow_style=False)
open('demo.yml', 'w').write(result)

demo.yml :

apiVersion: apps/v1
kind: Deployment
metadata:
 name: podinfo
 namespace: yaml-demo
spec:
 replicas: 1
 selector:
  matchLabels:
   app: podinfo
 template:
  metadata:
   labels:
    app: podinfo
  spec:
   containers:
   - image: quay.io/stefanprodan/podinfo:0.3.0
    name: podinfod
    ports:
    - containerPort: 9898

補(bǔ)充知識(shí):Python的PyYAML模塊詳解

簡(jiǎn)介

Python的PyYAML模塊是Python的YAML解析器和生成器。

安裝

簡(jiǎn)單安裝

pip install pyyaml

從源碼安裝

下載源碼包PyYAML-3.13.tar.gz 并解壓,在命令行下切換到解壓后的包目錄內(nèi)并執(zhí)行如下命令:

python setup.py install

如果想使用比純Python版本更快的LibYAML綁定,需要先下載并安裝LibYAML,然后在安裝PyYAML的時(shí)候執(zhí)行如下命令:

python setup.py --with-libyaml install

為了使用基于LibYAML的解析器和生成器,請(qǐng)使用 CParser 和 CEmitter 類。例如:

from yaml import load, dump
try:
  from yaml import Cloader as Loader, CDumper as Dumper
except ImportError:
  from yaml import Loader, Dumper

# ...

data = load(stream, Loader=Loader)

# ...

output = dump(data, Dumper=Dumper)

請(qǐng)注意,基于純Python和基于LibYAML的YAML解析器和生成器之間有一些細(xì)微但并不真正重要的區(qū)別。

最常被問(wèn)到的問(wèn)題

為什么如下所示的YAML文檔在反序列化后再序列化,得到的YAML文檔的格式與原來(lái)不一樣?

import yaml
document = """
a: 1
b:
 c: 3
 d: 4
"""
print(yaml.dump(yaml.load(document)))

其中,上面代碼的輸出為:

a: 1
b: {c: 3, d: 4}

關(guān)于這個(gè)問(wèn)題,其實(shí),盡管最后得到的YAML文檔的樣式與原來(lái)的文檔的樣式不一致,但是卻是正確的結(jié)果。

因?yàn)镻yYAML默認(rèn)會(huì)根據(jù)一個(gè)集合中是否有嵌套的集合來(lái)決定用哪種格式表示這個(gè)集合。如果一個(gè)集合中嵌套有其他集合,那么會(huì)使用塊樣式來(lái)表示,否則會(huì)使用流樣式來(lái)表示。

如果想要集合總是以塊樣式表示,可以將 dump() 方法的 default_flow_style 參數(shù)值設(shè)為 False ,如下所示:

print(yaml.dump(yaml.load(document), default_flow_style=False))

上面代碼的輸出為:

a: 1
b:
c: 3
d: 4

使用詳解

先導(dǎo)入 yaml 模塊:

import yaml

加載YAML

警告:調(diào)用 yaml.load 處理從不可信任的源接收的數(shù)據(jù)可能存在風(fēng)險(xiǎn)。yaml.load 與 pickle.load 的功能一樣強(qiáng)大,可以調(diào)用所有Python函數(shù)。

yaml.load 函數(shù)的作用是用來(lái)將YAML文檔轉(zhuǎn)化成Python對(duì)象。如下所示:

>>> yaml.load("""
... - Hesperiidae
... - Papilionidae
... - Apatelodidae
... - Epiplemidae
... """)
['Hesperiidae', 'Papilionidae', 'Apatelodidae', 'Epiplemidae']

yaml.load 函數(shù)可以接受一個(gè)表示YAML文檔的字節(jié)字符串、Unicode字符串、打開(kāi)的二進(jìn)制文件對(duì)象或者打開(kāi)的文本文件對(duì)象作為參數(shù)。若參數(shù)為字節(jié)字符串或文件,那么它們必須使用 utf-8 、utf-16 或者 utf-16-le 編碼。yaml.load 會(huì)檢查字節(jié)字符串或者文件對(duì)象的BOM(byte order mark)并依此來(lái)確定它們的編碼格式。如果沒(méi)有發(fā)現(xiàn) BOM ,那么會(huì)假定他們使用 utf-8 格式的編碼。

yaml.load 方法的返回值為一個(gè)Python對(duì)象,如下所示:

>>> yaml.load("'hello': '?'")
{'hello': '\uf8ff'}
>>> with open('document.yaml', 'w') as f:
...   f.writelines('- Python\n- Ruby\n- Java')
... 
>>> stream = open('document.yaml')
>>> yaml.load(stream)
['Python', 'Ruby', 'Java']


如果字符串或者文件中包含多個(gè)YAML文檔,那么可以使用 yaml.load_all 函數(shù)將它們?nèi)糠葱蛄谢?,得到的是一個(gè)包含所有反序列化后的YAML文檔的生成器對(duì)象:

>>> documents = """
... name: bob
... age: 18
... ---
... name: alex
... age: 20
... ---
... name: jason
... age: 16
... """
>>> datas = yaml.load_all(documents)
>>> datas
<generator object load_all at 0x105682228>
>>> for data in datas:
...   print(data)
... 
{'name': 'bob', 'age': 18}
{'name': 'alex', 'age': 20}
{'name': 'jason', 'age': 16}

PyYAML允許用戶構(gòu)造任何類型的Python對(duì)象,如下所示:

>>> document = """
... none: [~, null]
... bool: [true, false, on, off]
... int: 55
... float: 3.1415926
... list: [Red, Blue, Green, Black]
... dict: {name: bob, age: 18}
... """
>>> yaml.load(document)
{'none': [None, None], 'bool': [True, False, True, False], 'int': 55, 'float': 3.1415926, 'list': ['Red', 'Blue', 'Green', 'Black'], 'dict': {'name': 'bob', 'age': 18}}

即使是Python 類的實(shí)例,也可以使用標(biāo)簽 !!python/object 來(lái)進(jìn)行構(gòu)建,如下所示:

>>> class Person:
...   def __init__(self, name, age, gender):
...     self.name = name
...     self.age = age
...     self.gender = gender
...   def __repr__(self):
...     return f"{self.__class__.__name__}(name={self.name!r}, age={self.age!r}, gender={self.gender!r})"
... 
>>> yaml.load("""
... !!python/object:__main__.Person
... name: Bob
... age: 18
... gender: Male
... """)
Person(name='Bob', age=18, gender='Male')

注意,如果從不信任的源(例如互聯(lián)網(wǎng))接收一個(gè)YAML文檔并由此構(gòu)建一個(gè)任意的Python對(duì)象可能存在一定的風(fēng)險(xiǎn)。而使用 yaml.safe_load 方法能夠?qū)⑦@個(gè)行為限制為僅構(gòu)造簡(jiǎn)單的Python對(duì)象,如整數(shù)或者列表。

定義一個(gè)繼承自yaml.YAMLObject 類的子類,然后將這個(gè)子類的類屬性 yaml_loader 的值設(shè)置為 yaml.SafeLoader ,這樣,這個(gè)類的對(duì)象就被標(biāo)記為是安全的,從而可以被 yaml.safe_load 方法識(shí)別。不過(guò)有一點(diǎn)需要注意,在反序列化這樣的Python對(duì)象時(shí),只能使用 safe_load 和 safe_load_all 方法。

轉(zhuǎn)儲(chǔ)YAML

yaml.dump 函數(shù)接受一個(gè)Python對(duì)象并生成一個(gè)YAML文檔。

>>> import yaml
>>> emp_info = { 'name': 'Lex',
... 'department': 'SQA',
... 'salary': 8000,
... 'annual leave entitlement': [5, 10]
... }
>>> print(yaml.dump(emp_info))
annual leave entitlement: [5, 10]
department: SQA
name: Lex
salary: 8000


yaml.dump 可以接受第二個(gè)可選參數(shù),用于寫入生成的YAML文本,這個(gè)參數(shù)的值可以是打開(kāi)的文本或者二進(jìn)制文件對(duì)象。如果不提供這個(gè)可選參數(shù),則直接返回生成的YAML文檔。

>>> with open('document.yaml', 'w') as f:
...   yaml.dump(emp_info, f)
... 
>>> import os
>>> os.system('cat document.yaml')
annual leave entitlement: [5, 10]
department: SQA
name: Lex
salary: 8000
0

如果要將多個(gè)Python對(duì)象序列化到一個(gè)YAML流中,可以使用 yaml.dump_all 函數(shù)。該函數(shù)接受一個(gè)Python的列表或者生成器對(duì)象作為第一個(gè)參數(shù),表示要序列化的多個(gè)Python對(duì)象。

>>> obj = [{'name': 'bob', 'age': 19}, {'name': 20, 'age': 23}, {'name': 'leo', 'age': 25}]
>>> print(yaml.dump_all(obj))
{age: 19, name: bob}
--- {age: 23, name: 20}
--- {age: 25, name: leo}

你甚至可以序列化一個(gè)Python類的實(shí)例,如下所示:

>>> class Person:
...   def __init__(self, name, age, gender):
...     self.name = name
...     self.age = age
...     self.gender = gender
...   def __repr__(self):
...     return f"{self.__class__.__name__}(name={self.name!r}, age={self.age!r}, gender={self.gender!r})"
... 
>>> print(yaml.dump(Person('Lucy', 26, 'Female')))
!!python/object:__main__.Person {age: 26, gender: Female, name: Lucy}

yaml.dump 和 yaml.dump_all 方法還支持多個(gè)關(guān)鍵字參數(shù),用來(lái)指定生成的YAML流中YAML文檔的樣式和是否包含其他信息。下面就來(lái)詳細(xì)介紹下每個(gè)參數(shù)的含義和用法。

stream

指定由于輸出YAML流的打開(kāi)的文件對(duì)象。默認(rèn)值為 None,表示作為函數(shù)的返回值返回。

default_flow_style

是否默認(rèn)以流樣式顯示序列和映射。默認(rèn)值為 None,表示對(duì)于不包含嵌套集合的YAML流使用流樣式。設(shè)置為 True 時(shí),序列和映射使用塊樣式。

default_style

默認(rèn)值為 None。表示標(biāo)量不使用引號(hào)包裹。設(shè)置為 '"' 時(shí),表示所有標(biāo)量均以雙引號(hào)包裹。設(shè)置為 "'" 時(shí),表示所有標(biāo)量以單引號(hào)包裹。

canonical

是否以規(guī)范形式顯示YAML文檔。默認(rèn)值為 None,表示以其他關(guān)鍵字參數(shù)設(shè)置的值進(jìn)行格式化,而不使用規(guī)范形式。設(shè)置為 True 時(shí),將以規(guī)范形式顯示YAML文檔中的內(nèi)容。

indent

表示縮進(jìn)級(jí)別。默認(rèn)值為 None, 表示使用默認(rèn)的縮進(jìn)級(jí)別(兩個(gè)空格),可以設(shè)置為其他整數(shù)。

width

表示每行的大寬度。默認(rèn)值為 None,表示使用默認(rèn)的寬度80。

allow_unicode

是否允許YAML流中出現(xiàn)unicode字符。默認(rèn)值為 False,會(huì)對(duì)unicode字符進(jìn)行轉(zhuǎn)義。設(shè)置為 True 時(shí),YAML文檔中將正常顯示unicode字符,不會(huì)進(jìn)行轉(zhuǎn)義。

line_break

設(shè)置換行符。默認(rèn)值為 None,表示換行符為 '',即空。可以設(shè)置為 \n、\r 或 \r\n。

encoding

使用指定的編碼對(duì)YAML流進(jìn)行編碼,輸出為字節(jié)字符串。默認(rèn)值為 None,表示不進(jìn)行編碼,輸出為一般字符串。

explicit_start

每個(gè)YAML文檔是否包含顯式的指令結(jié)束標(biāo)記。默認(rèn)值為 None,表示流中只有一個(gè)YAML文檔時(shí)不包含顯式的指令結(jié)束標(biāo)記。設(shè)置為 True 時(shí),YAML流中的所有YAML文檔都包含一個(gè)顯式的指令結(jié)束標(biāo)記。

explicit_end

每個(gè)YAML文檔是否包含顯式的文檔結(jié)束標(biāo)記。默認(rèn)值為 None,表示流中的YAML文檔不包含顯式的文檔結(jié)束標(biāo)記。設(shè)置為 True 時(shí),YAML流中的所有YAML文檔都包含一個(gè)顯式的文檔結(jié)束標(biāo)記。

version

用于在YAML文檔中指定YAML的版本號(hào),默認(rèn)值為 None,表示不在YAML中當(dāng)中指定版本號(hào)??梢栽O(shè)置為一個(gè)包含兩個(gè)元素的元組或者列表,但是第一個(gè)元素必須為1,否則會(huì)引發(fā)異常。當(dāng)前可用的YAML的版本號(hào)為1.0、1.1 和1.2。

tags

用于指定YAML文檔中要包含的標(biāo)簽。默認(rèn)值為 None,表示不指定標(biāo)簽指令??梢栽O(shè)置為一個(gè)包含標(biāo)簽的字典,字典中的鍵值對(duì)對(duì)應(yīng)各個(gè)不同的標(biāo)簽名和值。

>>> data = {'code': 200, 'status': 'success', 'message': [10, True, "Got it"]}
>>> print(yaml.dump(data, version=(1, 2))) # 設(shè)置YAML版本
%YAML 1.2
---
code: 200
message: [10, true, Got it]
status: success

>>> print(yaml.dump(data, version=(1, 2), tags={'!name!': 'test'})) # 設(shè)置標(biāo)簽指令
%YAML 1.2
%TAG !name! test
---
code: 200
message: [10, true, Got it]
status: success

>>> print(yaml.dump(data, # 設(shè)置使用塊樣式
...         version=(1, 2),
...         tags={'!name!': 'test'},
...         default_flow_style=False))
%YAML 1.2
%TAG !name! test
---
code: 200
message:
- 10
- true
- Got it
status: success

>>> print(yaml.dump(data, # 設(shè)置標(biāo)量使用單引號(hào)包裹
...         version=(1, 2),
...         tags={'!name!': 'test'},
...         default_flow_style=False,
...         default_))
%YAML 1.2
%TAG !name! test
---
'code': !!int '200'
'message':
- !!int '10'
- !!bool 'true'
- 'Got it'
'status': 'success'

>>> print(yaml.dump(data, # 設(shè)置標(biāo)量使用雙引號(hào)包裹 
...         version=(1, 2),
...         tags={'!name!': 'test'},
...         default_flow_style=False,
...         default_style='"'))
%YAML 1.2
%TAG !name! test
---
"code": !!int "200"
"message":
- !!int "10"
- !!bool "true"
- "Got it"
"status": "success"

>>> print(yaml.dump(data, # 設(shè)置YAML文檔包含顯式的指令結(jié)束標(biāo)記和文檔結(jié)束標(biāo)記
...         explicit_start=True,
...         explicit_end=True))
---
code: 200
message: [10, true, Got it]
status: success
...

>>> print(yaml.dump(data, canonical=True)) # 設(shè)置文檔使用規(guī)范形式
---
!!map {
 ? !!str "code"
 : !!int "200",
 ? !!str "message"
 : !!seq [
  !!int "10",
  !!bool "true",
  !!str "Got it",
 ],
 ? !!str "status"
 : !!str "success",
}

>>> print(yaml.dump(data, encoding='utf-8')) # 將YAML流使用utf-8格式進(jìn)行編碼
b'code: 200\nmessage: [10, true, Got it]\nstatus: success\n'
>>> user_info = {'name': '張學(xué)友', 'age': 57, '外號(hào)': ['歌神', '烏蠅哥']}
>>> print(yaml.dump(user_info)) # 若不設(shè)置 allow_unicode 參數(shù),則unicode字符會(huì)轉(zhuǎn)義
age: 57
name: "\u5F20\u5B66\u53CB"
"\u5916\u53F7": ["\u6B4C\u795E", "\u4E4C\u8747\u54E5"]
 
>>> print(yaml.dump(user_info, allow_unicode=True)) # 設(shè)置允許包含unicode字符
age: 57
name: 張學(xué)友
外號(hào): [歌神, 烏蠅哥]

構(gòu)造、表示和解析

可以定義自己的特定于應(yīng)用程序的標(biāo)記。最簡(jiǎn)單的方法是定義 yaml.YAMLObject 的子類,如下所示:

>>> class Person(yaml.YAMLObject):
...   yaml_tag = '!Person'
...   def __init__(self, name, age, gender):
...     self.name = name
...     self.age = age
...     self.gender = gender
...   def __repr__(self):
...     return f"{self.__class__.__name__}(name={self.name!r}, age={self.age!r}, gender={self.gender!r})"
...

如上的定義已經(jīng)足夠自動(dòng)化反序列化和序列化 Person 對(duì)象:

>>> text = """
... --- !Person
... name: Bob
... age: 22
... gender: Male
... """
>>> yaml.load(text)
Person(name='Bob', age=22, gender='Male')
>>> print(yaml.dump(Person('Bob', 22, 'Male')))
!Person {age: 22, gender: Male, name: Bob}

yaml.YAMLObject 使用元類魔法注冊(cè)了一個(gè)用來(lái)將YAML節(jié)點(diǎn)轉(zhuǎn)換為類實(shí)例的 constructors 和用來(lái)將YAML節(jié)點(diǎn)反序列化為Python類實(shí)例的表示器 representers。

如果你不想使用元類,你可以使用 yaml.add_constructor 和 yaml.add_representer 來(lái)注冊(cè)你的 constructors 和 representers。如下所示:

>>> class Dice(tuple):
...   def __new__(cls, a, b):
...     return tuple.__new__(cls, [a, b])
...   def __repr__(self):
...     return 'Dice(%s, %s)' % self
... 
>>> print(Dice(3, 6))
Dice(3, 6)

默認(rèn)的 Dice 對(duì)象的表示看起來(lái)不太美觀:

>>> print(yaml.dump(Dice(3, 6)))
!!python/object/new:__main__.Dice
- !!python/tuple [3, 6]

假如你想要一個(gè) Dice 對(duì)象序列化后表示成 AdB 這樣的形式,例如:

print(yaml.dump(Dict(3, 6))) # 期待輸出為:3d6

首先,需要定義一個(gè)用來(lái)將 Dict 對(duì)象轉(zhuǎn)化成使用 !dict 標(biāo)簽標(biāo)記的標(biāo)量節(jié)點(diǎn)的 *representers,然后注冊(cè)它,如下所示:

>> def dice_representer(dumper, data):
...   return dumper.represent_scalar('!dice', '%sd%s' % data)
... 
>>> yaml.add_representer(Dice, dice_representer)

現(xiàn)在,序列化一個(gè) Dice 對(duì)象的實(shí)例后的輸入就與期望的一樣了:

>>> yaml.add_representer(Dice, dice_representer)
>>> print(yaml.dump({'gold': Dice(10, 6)}))
{gold: !dice '10d6'}

下面,我們?cè)賮?lái)實(shí)現(xiàn)一個(gè)將使用 !dice 標(biāo)簽標(biāo)記的標(biāo)量節(jié)點(diǎn)轉(zhuǎn)化為 Dice 對(duì)象的 constructor 并注冊(cè)它:

>>> def dice_constructor(loader, node):
...   value = loader.construct_scalar(node)
...   a, b = map(int, value.split('d'))
...   return Dice(a, b)
... 
>>> yaml.add_constructor('!dice', dice_constructor)


然后,你就可以加載一個(gè) Dice 對(duì)象了:

>>> text = 'initial hit points: !dice 8d4'
>>> print(yaml.load(text))
{'initial hit points': Dice(8, 4)}

如果你不想在任何地方都指定 !dice 標(biāo)簽,那么可以使用 add_implicit_resolver 函數(shù)告訴PyYAML所有未標(biāo)記的形如 XdY 的普通標(biāo)量具有顯式標(biāo)簽 !dice,如下所示:

>>> import re
>>> pattern = re.compile(r'^\d+d\d+$')
>>> yaml.add_implicit_resolver('!dice', pattern)

現(xiàn)在,在定義 Dice 對(duì)象的時(shí)候可以不使用標(biāo)簽了,如下所示:

>>> print(yaml.dump({'treasure': Dice(10, 20)}))
{treasure: 10d20}

>>> print(yaml.load('damage: 5d10'))
{'damage': Dice(5, 10)}

當(dāng)將一個(gè)對(duì)象標(biāo)記為安全的時(shí)候,在反序列化這樣的對(duì)象時(shí)只能使用 safe_load 或 safe_load_all 方法,否則會(huì)報(bào)錯(cuò),如下所示:

>>> class Person(yaml.YAMLObject):
...   yaml_tag = '!Person'
...   yaml_loader = yaml.SafeLoader
...   def __init(self, name, age, gender):
...     self.name = name
...     self.age = age
...     self.gender = gender
...   def __repr__(self):
...     return f"Person(name={self.name!r}, age={self.age!r}, gender={self.gender!r})"
... 
>>> text = """
... !Person
... name: Bob
... age: 22
... gender: Male
... """
>>> yaml.load(text) # 不使用 safe_load 或 safe_load_all 方法會(huì)報(bào)錯(cuò)
Traceback (most recent call last):
 ...
yaml.constructor.ConstructorError: could not determine a constructor for the tag '!Person'
 in "<unicode string>", line 2, column 1:
  !Person
  ^
>>> yaml.safe_load(text) # 使用 safe_load 方法可以正常反序列化
Person(name='Bob', age=22, gender='Male')

YAML語(yǔ)法

這一部分將介紹最常見(jiàn)的YAML結(jié)構(gòu)以及相應(yīng)的Python對(duì)象。

文檔

YAML流是零個(gè)或多個(gè)YAML文檔的集合??盏腨AML流不包含YAML文檔。YAML文檔間用文檔開(kāi)始標(biāo)記 --- 進(jìn)行分隔。YAML文檔可以包含一個(gè)可選的文檔結(jié)束標(biāo)記 ... 。如果流中只有一個(gè)文檔,那么可以不使用文檔開(kāi)始標(biāo)記。包含文檔開(kāi)始標(biāo)記的文檔可以稱為 顯式文檔 ,不包含文檔開(kāi)始標(biāo)記的文檔可以稱為 隱式文檔。

下面是一個(gè)隱式文檔:

- Multimedia
- Internet
- Education

下面是一個(gè)顯式文檔:

---
- Afterstep
- CTWM
- Oroborus
...

下面是一個(gè)包含多個(gè)文檔的YAML流:

---
- Employee
- Manager
- CEO
- CTO
---
- Student
---
- C
- C# # YAML中使用‘#' 來(lái)表示注釋(‘#'前面要有一個(gè)空格)
- C++
- Cold Fusion

塊序列

在塊內(nèi)容中,使用破折號(hào)(dash) - 后跟一個(gè)空格(Space)來(lái)表示序列中的項(xiàng)。

下面是一個(gè)包含塊序列的文檔:

- id
- name
- age

上述文檔表示的一個(gè)如下的Python對(duì)象:

['id', 'name', 'age']

塊序列是可以嵌套的:

-
- Python
- Ruby
- JavaScript
- PHP
-
- Unix
- Linux
- Windows

上述文檔表示如下的Python對(duì)象:

[['Python', 'Ruby', 'JavaScript', 'PHP'], ['Unix', 'Linux', 'Windows']]

在嵌套的塊序列中,內(nèi)層的序列可以直接從當(dāng)前行開(kāi)始而不必從新的一行開(kāi)始,如下所示:

- - Python
- Ruby
- JavaScript
- PHP
- - Unix
- Linux
- Windows

塊序列中可以嵌套在塊映射之中,在這種情況下,塊序列不需要縮進(jìn),如下所示:

Programing Languages:
- Java
- Swift
- C++
- Go
Operation System:
- Unix
- Linux
- Windows
- OSX

上述文檔表示如下的Python對(duì)象:

{'Programing Languages': ['Java', 'Swift', 'C++', 'Go'],
 'Operation System': ['Unix', 'Linux', 'Windows']}

塊映射

塊內(nèi)容中,使用冒號(hào) : 后跟一個(gè)空格來(lái)分隔映射中的鍵和值。

name: bob
age: 28
gender: Male

上述文檔表示如下的Python對(duì)象:

{'name': 'bob', 'age': 28, 'gender': 'Male'}

復(fù)雜的鍵使用問(wèn)號(hào) ? 后跟一個(gè)空格來(lái)表示,如下所示:

? !!python/tuple [0, 0]
: Start
? !!python/tuple [3, 5]
: End

上述文檔表示如下的Python 對(duì)象:

{(0, 0): 'Start', (3, 5): 'End'}

塊映射是可以嵌套的,如下所示:

Employee:
 Job_title: Employee
 Salary: 5000
 Annual Leave: 10
Manager:
 Job_title: Manager
 Salary: 8000
 Annual Leave: 15

上述文檔表示如下的Python對(duì)象:

{'Employee': {'Job_title': 'Employee', 'Salary': 5000, 'Annual Leave': 10},
'Manager': {' Job_title': 'Manager', 'Salary': 8000, 'Annual Leave': 15}}

塊映射可以嵌套在塊序列中,如下所示:

- name: PyYAML
status: 4
license: MIT
language: Python
- name: PySyck
status: 5
license: BSD
language: Python

上述文檔表示如下的Python對(duì)象:

[{'name': 'PyYAML', 'status': 4, 'license': 'MIT', 'language': 'Python'},
{'name': 'PySyck', 'status': 5, 'license': 'BSD', 'language': 'Python'}]

流集合

YAML中流集合的語(yǔ)法與Python中列表和字典結(jié)構(gòu)的語(yǔ)法很像,如下所示:

{ str: [15, 17], con: [16, 16], dex: [17, 18], wis: [16, 16], int: [10, 13], chr: [5, 8] }

上述文檔表示如下的Python對(duì)象:

{'dex': [17, 18], 'int': [10, 13], 'chr': [5, 8], 'wis': [16, 16], 'str': [15, 17], 'con': [16, 16]}

標(biāo)量

YAML中的標(biāo)量共有5中樣式,其中塊標(biāo)量有兩種樣式:

文字樣式(literal style)

折疊樣式(folded style)

流標(biāo)量有三種樣式:

普通樣式(plain style)

單引號(hào)樣式(single-quoted style)

雙引號(hào)樣式(double-quoted style)

這五種樣式的示例如下:

plain: Hello World
single-quoted: '所有內(nèi)容都會(huì)原樣輸出'
double-quoted: "需要用反斜杠轉(zhuǎn)移特殊字符"
literal: |
每一行
都會(huì)
包含換行符
中間的每一個(gè)空行

都會(huì)用換行符代替
folded: >
除過(guò)最后一行的
換行符
會(huì)保留
其他行末尾的換行符
都會(huì)使用一個(gè)空格代替
中間的空行

將會(huì)使用一個(gè)換行符代替

上述文檔表示如下的Python對(duì)象:

{'plain': 'Hello World',
'single-quoted': '所有內(nèi)容都會(huì)原樣輸出',
'double-quoted': '需要用反斜杠轉(zhuǎn)移特殊字符',
'literal': '每一行\(zhòng)n都會(huì)\n包含換行符\n中間的每一個(gè)空行\(zhòng)n\n都會(huì)用換行符代替\n',
'folded': '除過(guò)最后一行的 換行符 會(huì)保留 其他行末尾的換行符 都會(huì)使用一個(gè)空格代替 中間的空行\(zhòng)n將會(huì)使用一個(gè)換行符代替\n'}


每種樣式都有其特點(diǎn)。普通標(biāo)量不使用指示符來(lái)表示其開(kāi)始和結(jié)束,因此它是最受限制的樣式。普通標(biāo)量自然適用于表示參數(shù)和屬性的名稱

使用單引號(hào)標(biāo)量,可以表示不包含特殊字符的任何值。單引號(hào)標(biāo)量不存在轉(zhuǎn)義,除非是一對(duì)相鄰的引號(hào) '' 被單引號(hào)所替換”。

雙引號(hào)是最強(qiáng)大的樣式,也是惟一可以表示任何標(biāo)量值的樣式。雙引號(hào)標(biāo)量?jī)?nèi)的字符允許轉(zhuǎn)義。使用轉(zhuǎn)義序列 \x* 和 \u*** ,可以表達(dá)任何ASCII或Unicode字符。

塊標(biāo)量樣式有兩種:文字樣式和折疊樣式。文字樣式是最適合于大型文本塊(如源代碼)的樣式。折疊樣式類似于文字樣式,但是兩個(gè)相鄰的非空行中間的換行符會(huì)被替換成一個(gè)空格從而變成一行。

別名

使用YAML可以表示任何類圖結(jié)構(gòu)的對(duì)象。如果希望從文檔的不同部分引用相同的對(duì)象,則需要使用錨和別名。

其中,錨用 & 表示,別名用 * 表示。下面的例子將會(huì)演示錨和別名的使用:

emp1: &A
 name: bob
 age: 28
 gender: Male
emp2: *A

上述文檔表示如下的Python對(duì)象:

{'emp1': {'name': 'bob', 'age': 28, 'gender': 'Male'},
'emp2': {'name': 'bob', 'age': 28, 'gender': 'Male'}}

PyYAML現(xiàn)在已經(jīng)支持遞歸對(duì)象,下面的文檔表示一個(gè)Python的列表,這個(gè)列表的元素是這個(gè)列表自身。

&A [ *A ]

標(biāo)簽

標(biāo)簽用來(lái)標(biāo)識(shí)節(jié)點(diǎn)的數(shù)據(jù)類型。標(biāo)準(zhǔn)的YAML標(biāo)簽的定義可以參考該文檔:

http://yaml.org/type/index.html

標(biāo)簽可以是隱式地,如下所示:

boolen: true
integer: 3
float: 3.14

上述文檔表示如下的Python對(duì)象:

{'boolean': True, 'integer': 3, 'float': 3.14}

標(biāo)簽也可以是顯式的,如下所示:

boolean: !!bool "true"
integer: !!int "3"
float: !!float "3.14"

上述文檔表示如下的Python對(duì)象:

{'boolean': True, 'integer': 3, 'float': 3.14}

沒(méi)有顯式定義標(biāo)簽的普通標(biāo)量受制于隱式標(biāo)簽解析。隱式標(biāo)簽解析根據(jù)一組正則表達(dá)式檢查標(biāo)量值,如果其中一個(gè)匹配,則為標(biāo)量分配相應(yīng)的標(biāo)記。PyYAML允許應(yīng)用程序添加自定義隱式標(biāo)簽解析器。

YAML標(biāo)簽和Python3 對(duì)象

YAML 標(biāo)簽Python對(duì)象
標(biāo)準(zhǔn)的YAML標(biāo)簽
!!nullNone
!!boolbool
!!intint
!!floatfloat
!!binarybytes
!!timestampdatetime.datetime
!!omap, !!pairs元素為一個(gè)二元組的list
!!setset
!!strstr
!!seqlist
!!mapdict
Python的特殊標(biāo)簽
!!python/noneNone
!!python/boolbool
!!python/bytesbytes
!!python/strstr
!!python/unicodestr
!!python/intint
!!python/longint
!!python/floatfloat
!!python/complexcomplex
!!python/listlist
!!python/tupletuple
!!python/dictdict
復(fù)雜的Python標(biāo)簽
!!python/name:module.namemodule.name
!!python/module:package.modulepackage.module
!!python/object:module.clsmodule.cls 的實(shí)例
!!python/object/new:module.clsmodule.cls 的實(shí)例
!!python/object/apply:module.func方法 func(...)的返回值

字符串轉(zhuǎn)換

在Python3中,str 類型的對(duì)象將被轉(zhuǎn)變成使用標(biāo)簽 !!str 標(biāo)識(shí)的標(biāo)量;bytes 類型的對(duì)象將被轉(zhuǎn)變成使用標(biāo)簽 !!binary 標(biāo)識(shí)的標(biāo)量。為了考慮兼容性,標(biāo)簽 !!python/str 和 !!python/unicode 仍然可以使用,被其標(biāo)識(shí)的標(biāo)量將被轉(zhuǎn)變成 str 類型的對(duì)象。

名稱和模塊

要表示靜態(tài)的Python對(duì)象,如函數(shù)和類,可以使用復(fù)雜的標(biāo)簽Python !!python/name 。下面的例子演示了如何表示yaml模塊中的dump方法:

!!python/name:yaml.dump

類似的,模塊可以使用標(biāo)簽 !!python/module :

!!python/module.yaml

對(duì)象

任何 pickleable 對(duì)象都可以使用標(biāo)簽 !!python/object 來(lái)序列化:

!!python/object:module.Class { attribute: value, ... }

為了支持 pickle 協(xié)議,PyYAML提供了兩個(gè)附加的標(biāo)簽

!!python/object/new:module.Class 和 !!python/object/apply:module.function

這兩個(gè)標(biāo)簽的使用方法如下:

!!python/object/new:module.Class
args: [argument, ...]
kwds: {key: value, ...}
stat: ...
listitems: [item, ...]
dictitems: [key: value, ...]

!!python/object/apply:module.function
args: [argument, ...]
kwds: {key: value, ...}
state: ...
listitems: [item, ...]
dictitems: [key: value, ...]

“python如何操作yaml方法講解”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

網(wǎng)站名稱:python如何操作yaml方法講解-創(chuàng)新互聯(lián)
路徑分享:http://muchs.cn/article4/dhghie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開(kāi)發(fā)、定制網(wǎng)站靜態(tài)網(wǎng)站、微信公眾號(hào)用戶體驗(yàn)、自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司