本篇內(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à)格咨詢:189820811081. 安裝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)簽 | |
!!null | None |
!!bool | bool |
!!int | int |
!!float | float |
!!binary | bytes |
!!timestamp | datetime.datetime |
!!omap, !!pairs | 元素為一個(gè)二元組的list |
!!set | set |
!!str | str |
!!seq | list |
!!map | dict |
Python的特殊標(biāo)簽 | |
!!python/none | None |
!!python/bool | bool |
!!python/bytes | bytes |
!!python/str | str |
!!python/unicode | str |
!!python/int | int |
!!python/long | int |
!!python/float | float |
!!python/complex | complex |
!!python/list | list |
!!python/tuple | tuple |
!!python/dict | dict |
復(fù)雜的Python標(biāo)簽 | |
!!python/name:module.name | module.name |
!!python/module:package.module | package.module |
!!python/object:module.cls | module.cls 的實(shí)例 |
!!python/object/new:module.cls | module.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)
猜你還喜歡下面的內(nèi)容