python操作yaml說明
1. 安裝PyYAML
pip install PyYAML
2. 加載yaml文件
直接使用yaml.load()函數(shù)
demo.yml :
kind: DeploymentapiVersion: apps/v1metadata: name: podinfo namespace: yaml-demospec: 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 yamlimport jsonresult = 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 yamld = { '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/v1kind: Deploymentmetadata: name: podinfo namespace: yaml-demospec: 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, dumptry: from yaml import Cloader as Loader, CDumper as Dumperexcept ImportError: from yaml import Loader, Dumper# ...data = load(stream, Loader=Loader)# ...output = dump(data, Dumper=Dumper)
請(qǐng)注意,基于純Python和基于LibYAML的YAML解析器和生成器之間有一些細(xì)微但并不真正重要的區(qū)別。
最常被問到的問題
為什么如下所示的YAML文檔在反序列化后再序列化,得到的YAML文檔的格式與原來不一樣?
import yamldocument = '''a: 1b: c: 3 d: 4'''print(yaml.dump(yaml.load(document)))
其中,上面代碼的輸出為:
a: 1b: {c: 3, d: 4}
關(guān)于這個(gè)問題,其實(shí),盡管最后得到的YAML文檔的樣式與原來的文檔的樣式不一致,但是卻是正確的結(jié)果。
因?yàn)镻yYAML默認(rèn)會(huì)根據(jù)一個(gè)集合中是否有嵌套的集合來決定用哪種格式表示這個(gè)集合。如果一個(gè)集合中嵌套有其他集合,那么會(huì)使用塊樣式來表示,否則會(huì)使用流樣式來表示。
如果想要集合總是以塊樣式表示,可以將 dump() 方法的 default_flow_style 參數(shù)值設(shè)為 False ,如下所示:
print(yaml.dump(yaml.load(document), default_flow_style=False))
上面代碼的輸出為:
a: 1b:c: 3d: 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ù)的作用是用來將YAML文檔轉(zhuǎn)化成Python對(duì)象。如下所示:
>>> yaml.load('''... - Hesperiidae... - Papilionidae... - Apatelodidae... - Epiplemidae... ''')[’Hesperiidae’, ’Papilionidae’, ’Apatelodidae’, ’Epiplemidae’]
yaml.load 函數(shù)可以接受一個(gè)表示YAML文檔的字節(jié)字符串、Unicode字符串、打開的二進(jìn)制文件對(duì)象或者打開的文本文件對(duì)象作為參數(shù)。若參數(shù)為字節(jié)字符串或文件,那么它們必須使用 utf-8 、utf-16 或者 utf-16-le 編碼。yaml.load 會(huì)檢查字節(jié)字符串或者文件對(duì)象的BOM(byte order mark)并依此來確定它們的編碼格式。如果沒有發(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(’- Pythonn- Rubyn- 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 來進(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í)別。不過有一點(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: SQAname: Lexsalary: 8000
yaml.dump 可以接受第二個(gè)可選參數(shù),用于寫入生成的YAML文本,這個(gè)參數(shù)的值可以是打開的文本或者二進(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: SQAname: Lexsalary: 80000
如果要將多個(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ù),用來指定生成的YAML流中YAML文檔的樣式和是否包含其他信息。下面就來詳細(xì)介紹下每個(gè)參數(shù)的含義和用法。
stream
指定由于輸出YAML流的打開的文件對(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 或 rn。
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)。可以設(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)簽指令。可以設(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: 200message: [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: 200message: [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: 200message:- 10- true- Got itstatus: 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è)置標(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: 200message: [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: 200nmessage: [10, true, Got it]nstatus: successn’>>> user_info = {’name’: ’張學(xué)友’, ’age’: 57, ’外號(hào)’: [’歌神’, ’烏蠅哥’]}>>> print(yaml.dump(user_info)) # 若不設(shè)置 allow_unicode 參數(shù),則unicode字符會(huì)轉(zhuǎn)義age: 57name: 'u5F20u5B66u53CB''u5916u53F7': ['u6B4Cu795E', 'u4E4Cu8747u54E5'] >>> print(yaml.dump(user_info, allow_unicode=True)) # 設(shè)置允許包含unicode字符age: 57name: 張學(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è)用來將YAML節(jié)點(diǎn)轉(zhuǎn)換為類實(shí)例的 constructors 和用來將YAML節(jié)點(diǎn)反序列化為Python類實(shí)例的表示器 representers。
如果你不想使用元類,你可以使用 yaml.add_constructor 和 yaml.add_representer 來注冊(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ì)象的表示看起來不太美觀:
>>> 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è)用來將 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è)賮韺?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+dd+$’)>>> 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ǔ)法
這一部分將介紹最常見的YAML結(jié)構(gòu)以及相應(yīng)的Python對(duì)象。
文檔
YAML流是零個(gè)或多個(gè)YAML文檔的集合。空的YAML流不包含YAML文檔。YAML文檔間用文檔開始標(biāo)記 --- 進(jìn)行分隔。YAML文檔可以包含一個(gè)可選的文檔結(jié)束標(biāo)記 ... 。如果流中只有一個(gè)文檔,那么可以不使用文檔開始標(biāo)記。包含文檔開始標(biāo)記的文檔可以稱為 顯式文檔 ,不包含文檔開始標(biāo)記的文檔可以稱為 隱式文檔。
下面是一個(gè)隱式文檔:
- Multimedia- Internet- Education
下面是一個(gè)顯式文檔:
---- Afterstep- CTWM- Oroborus...
下面是一個(gè)包含多個(gè)文檔的YAML流:
---- Employee- Manager- CEO- CTO---- Student---- C- C# # YAML中使用‘#’ 來表示注釋(‘#’前面要有一個(gè)空格)- C++- Cold Fusion
塊序列
在塊內(nèi)容中,使用破折號(hào)(dash) - 后跟一個(gè)空格(Space)來表示序列中的項(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)前行開始而不必從新的一行開始,如下所示:
- - Python- Ruby- JavaScript- PHP- - Unix- Linux- Windows
塊序列中可以嵌套在塊映射之中,在這種情況下,塊序列不需要縮進(jìn),如下所示:
Programing Languages:- Java- Swift- C++- GoOperation System:- Unix- Linux- Windows- OSX
上述文檔表示如下的Python對(duì)象:
{’Programing Languages’: [’Java’, ’Swift’, ’C++’, ’Go’], ’Operation System’: [’Unix’, ’Linux’, ’Windows’]}
塊映射
塊內(nèi)容中,使用冒號(hào) : 后跟一個(gè)空格來分隔映射中的鍵和值。
name: bobage: 28gender: Male
上述文檔表示如下的Python對(duì)象:
{’name’: ’bob’, ’age’: 28, ’gender’: ’Male’}
復(fù)雜的鍵使用問號(hào) ? 后跟一個(gè)空格來表示,如下所示:
? !!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: 10Manager: 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: PyYAMLstatus: 4license: MITlanguage: Python- name: PySyckstatus: 5license: BSDlanguage: 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 Worldsingle-quoted: ’所有內(nèi)容都會(huì)原樣輸出’double-quoted: '需要用反斜杠轉(zhuǎn)移特殊字符'literal: |每一行都會(huì)包含換行符中間的每一個(gè)空行都會(huì)用換行符代替folded: >除過最后一行的換行符會(huì)保留其他行末尾的換行符都會(huì)使用一個(gè)空格代替中間的空行將會(huì)使用一個(gè)換行符代替
上述文檔表示如下的Python對(duì)象:
{’plain’: ’Hello World’,’single-quoted’: ’所有內(nèi)容都會(huì)原樣輸出’,’double-quoted’: ’需要用反斜杠轉(zhuǎn)移特殊字符’,’literal’: ’每一行n都會(huì)n包含換行符n中間的每一個(gè)空行nn都會(huì)用換行符代替n’,’folded’: ’除過最后一行的 換行符 會(huì)保留 其他行末尾的換行符 都會(huì)使用一個(gè)空格代替 中間的空行n將會(huì)使用一個(gè)換行符代替n’}
每種樣式都有其特點(diǎn)。普通標(biāo)量不使用指示符來表示其開始和結(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: Maleemp2: *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)簽用來標(biāo)識(shí)節(jié)點(diǎn)的數(shù)據(jù)類型。標(biāo)準(zhǔn)的YAML標(biāo)簽的定義可以參考該文檔:
http://yaml.org/type/index.html
標(biāo)簽可以是隱式地,如下所示:
boolen: trueinteger: 3float: 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}
沒有顯式定義標(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 來序列化:
!!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.Classargs: [argument, ...]kwds: {key: value, ...}stat: ...listitems: [item, ...]dictitems: [key: value, ...]!!python/object/apply:module.functionargs: [argument, ...]kwds: {key: value, ...}state: ...listitems: [item, ...]dictitems: [key: value, ...]
以上這篇python操作yaml說明就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. JavaWeb Servlet中url-pattern的使用2. jsp中sitemesh修改tagRule技術(shù)分享3. asp(vbscript)中自定義函數(shù)的默認(rèn)參數(shù)實(shí)現(xiàn)代碼4. React優(yōu)雅的封裝SvgIcon組件示例5. 輕松學(xué)習(xí)XML教程6. php網(wǎng)絡(luò)安全中命令執(zhí)行漏洞的產(chǎn)生及本質(zhì)探究7. ASP刪除img標(biāo)簽的style屬性只保留src的正則函數(shù)8. JSP servlet實(shí)現(xiàn)文件上傳下載和刪除9. ASP基礎(chǔ)知識(shí)VBScript基本元素講解10. 詳解瀏覽器的緩存機(jī)制
