python操作yaml說明
1. 安裝PyYAML
pip install PyYAML
2. 加載yaml文件
直接使用yaml.load()函數
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到yml文件
使用yaml.safe_dump()函數
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
補充知識:Python的PyYAML模塊詳解
簡介
Python的PyYAML模塊是Python的YAML解析器和生成器。
安裝
簡單安裝
pip install pyyaml
從源碼安裝
下載源碼包PyYAML-3.13.tar.gz 并解壓,在命令行下切換到解壓后的包目錄內并執行如下命令:
python setup.py install
如果想使用比純Python版本更快的LibYAML綁定,需要先下載并安裝LibYAML,然后在安裝PyYAML的時候執行如下命令:
python setup.py --with-libyaml install
為了使用基于LibYAML的解析器和生成器,請使用 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)
請注意,基于純Python和基于LibYAML的YAML解析器和生成器之間有一些細微但并不真正重要的區別。
最常被問到的問題
為什么如下所示的YAML文檔在反序列化后再序列化,得到的YAML文檔的格式與原來不一樣?
import yamldocument = '''a: 1b: c: 3 d: 4'''print(yaml.dump(yaml.load(document)))
其中,上面代碼的輸出為:
a: 1b: {c: 3, d: 4}
關于這個問題,其實,盡管最后得到的YAML文檔的樣式與原來的文檔的樣式不一致,但是卻是正確的結果。
因為PyYAML默認會根據一個集合中是否有嵌套的集合來決定用哪種格式表示這個集合。如果一個集合中嵌套有其他集合,那么會使用塊樣式來表示,否則會使用流樣式來表示。
如果想要集合總是以塊樣式表示,可以將 dump() 方法的 default_flow_style 參數值設為 False ,如下所示:
print(yaml.dump(yaml.load(document), default_flow_style=False))
上面代碼的輸出為:
a: 1b:c: 3d: 4
使用詳解
先導入 yaml 模塊:
import yaml
加載YAML
警告:調用 yaml.load 處理從不可信任的源接收的數據可能存在風險。yaml.load 與 pickle.load 的功能一樣強大,可以調用所有Python函數。
yaml.load 函數的作用是用來將YAML文檔轉化成Python對象。如下所示:
>>> yaml.load('''... - Hesperiidae... - Papilionidae... - Apatelodidae... - Epiplemidae... ''')[’Hesperiidae’, ’Papilionidae’, ’Apatelodidae’, ’Epiplemidae’]
yaml.load 函數可以接受一個表示YAML文檔的字節字符串、Unicode字符串、打開的二進制文件對象或者打開的文本文件對象作為參數。若參數為字節字符串或文件,那么它們必須使用 utf-8 、utf-16 或者 utf-16-le 編碼。yaml.load 會檢查字節字符串或者文件對象的BOM(byte order mark)并依此來確定它們的編碼格式。如果沒有發現 BOM ,那么會假定他們使用 utf-8 格式的編碼。
yaml.load 方法的返回值為一個Python對象,如下所示:
>>> 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’]
如果字符串或者文件中包含多個YAML文檔,那么可以使用 yaml.load_all 函數將它們全部反序列化,得到的是一個包含所有反序列化后的YAML文檔的生成器對象:
>>> 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允許用戶構造任何類型的Python對象,如下所示:
>>> 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 類的實例,也可以使用標簽 !!python/object 來進行構建,如下所示:
>>> 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’)
注意,如果從不信任的源(例如互聯網)接收一個YAML文檔并由此構建一個任意的Python對象可能存在一定的風險。而使用 yaml.safe_load 方法能夠將這個行為限制為僅構造簡單的Python對象,如整數或者列表。
定義一個繼承自yaml.YAMLObject 類的子類,然后將這個子類的類屬性 yaml_loader 的值設置為 yaml.SafeLoader ,這樣,這個類的對象就被標記為是安全的,從而可以被 yaml.safe_load 方法識別。不過有一點需要注意,在反序列化這樣的Python對象時,只能使用 safe_load 和 safe_load_all 方法。
轉儲YAML
yaml.dump 函數接受一個Python對象并生成一個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 可以接受第二個可選參數,用于寫入生成的YAML文本,這個參數的值可以是打開的文本或者二進制文件對象。如果不提供這個可選參數,則直接返回生成的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
如果要將多個Python對象序列化到一個YAML流中,可以使用 yaml.dump_all 函數。該函數接受一個Python的列表或者生成器對象作為第一個參數,表示要序列化的多個Python對象。
>>> 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}
你甚至可以序列化一個Python類的實例,如下所示:
>>> 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 方法還支持多個關鍵字參數,用來指定生成的YAML流中YAML文檔的樣式和是否包含其他信息。下面就來詳細介紹下每個參數的含義和用法。
stream
指定由于輸出YAML流的打開的文件對象。默認值為 None,表示作為函數的返回值返回。
default_flow_style
是否默認以流樣式顯示序列和映射。默認值為 None,表示對于不包含嵌套集合的YAML流使用流樣式。設置為 True 時,序列和映射使用塊樣式。
default_style
默認值為 None。表示標量不使用引號包裹。設置為 ’'’ 時,表示所有標量均以雙引號包裹。設置為 '’' 時,表示所有標量以單引號包裹。
canonical
是否以規范形式顯示YAML文檔。默認值為 None,表示以其他關鍵字參數設置的值進行格式化,而不使用規范形式。設置為 True 時,將以規范形式顯示YAML文檔中的內容。
indent
表示縮進級別。默認值為 None, 表示使用默認的縮進級別(兩個空格),可以設置為其他整數。
width
表示每行的最大寬度。默認值為 None,表示使用默認的寬度80。
allow_unicode
是否允許YAML流中出現unicode字符。默認值為 False,會對unicode字符進行轉義。設置為 True 時,YAML文檔中將正常顯示unicode字符,不會進行轉義。
line_break
設置換行符。默認值為 None,表示換行符為 ’’,即空??梢栽O置為 n、r 或 rn。
encoding
使用指定的編碼對YAML流進行編碼,輸出為字節字符串。默認值為 None,表示不進行編碼,輸出為一般字符串。
explicit_start
每個YAML文檔是否包含顯式的指令結束標記。默認值為 None,表示流中只有一個YAML文檔時不包含顯式的指令結束標記。設置為 True 時,YAML流中的所有YAML文檔都包含一個顯式的指令結束標記。
explicit_end
每個YAML文檔是否包含顯式的文檔結束標記。默認值為 None,表示流中的YAML文檔不包含顯式的文檔結束標記。設置為 True 時,YAML流中的所有YAML文檔都包含一個顯式的文檔結束標記。
version
用于在YAML文檔中指定YAML的版本號,默認值為 None,表示不在YAML中當中指定版本號??梢栽O置為一個包含兩個元素的元組或者列表,但是第一個元素必須為1,否則會引發異常。當前可用的YAML的版本號為1.0、1.1 和1.2。
tags
用于指定YAML文檔中要包含的標簽。默認值為 None,表示不指定標簽指令??梢栽O置為一個包含標簽的字典,字典中的鍵值對對應各個不同的標簽名和值。
>>> data = {’code’: 200, ’status’: ’success’, ’message’: [10, True, 'Got it']}>>> print(yaml.dump(data, version=(1, 2))) # 設置YAML版本%YAML 1.2---code: 200message: [10, true, Got it]status: success>>> print(yaml.dump(data, version=(1, 2), tags={’!name!’: ’test’})) # 設置標簽指令%YAML 1.2%TAG !name! test---code: 200message: [10, true, Got it]status: success>>> print(yaml.dump(data, # 設置使用塊樣式... 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, # 設置標量使用單引號包裹... 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, # 設置標量使用雙引號包裹 ... 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, # 設置YAML文檔包含顯式的指令結束標記和文檔結束標記... explicit_start=True,... explicit_end=True))---code: 200message: [10, true, Got it]status: success...>>> print(yaml.dump(data, canonical=True)) # 設置文檔使用規范形式---!!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格式進行編碼b’code: 200nmessage: [10, true, Got it]nstatus: successn’>>> user_info = {’name’: ’張學友’, ’age’: 57, ’外號’: [’歌神’, ’烏蠅哥’]}>>> print(yaml.dump(user_info)) # 若不設置 allow_unicode 參數,則unicode字符會轉義age: 57name: 'u5F20u5B66u53CB''u5916u53F7': ['u6B4Cu795E', 'u4E4Cu8747u54E5'] >>> print(yaml.dump(user_info, allow_unicode=True)) # 設置允許包含unicode字符age: 57name: 張學友外號: [歌神, 烏蠅哥]
構造、表示和解析
可以定義自己的特定于應用程序的標記。最簡單的方法是定義 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})'...
如上的定義已經足夠自動化反序列化和序列化 Person 對象:
>>> 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 使用元類魔法注冊了一個用來將YAML節點轉換為類實例的 constructors 和用來將YAML節點反序列化為Python類實例的表示器 representers。
如果你不想使用元類,你可以使用 yaml.add_constructor 和 yaml.add_representer 來注冊你的 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)
默認的 Dice 對象的表示看起來不太美觀:
>>> print(yaml.dump(Dice(3, 6)))!!python/object/new:__main__.Dice- !!python/tuple [3, 6]
假如你想要一個 Dice 對象序列化后表示成 AdB 這樣的形式,例如:
print(yaml.dump(Dict(3, 6))) # 期待輸出為:3d6
首先,需要定義一個用來將 Dict 對象轉化成使用 !dict 標簽標記的標量節點的 *representers,然后注冊它,如下所示:
>> def dice_representer(dumper, data):... return dumper.represent_scalar(’!dice’, ’%sd%s’ % data)... >>> yaml.add_representer(Dice, dice_representer)
現在,序列化一個 Dice 對象的實例后的輸入就與期望的一樣了:
>>> yaml.add_representer(Dice, dice_representer)>>> print(yaml.dump({’gold’: Dice(10, 6)})){gold: !dice ’10d6’}
下面,我們再來實現一個將使用 !dice 標簽標記的標量節點轉化為 Dice 對象的 constructor 并注冊它:
>>> 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)
然后,你就可以加載一個 Dice 對象了:
>>> text = ’initial hit points: !dice 8d4’>>> print(yaml.load(text)){’initial hit points’: Dice(8, 4)}
如果你不想在任何地方都指定 !dice 標簽,那么可以使用 add_implicit_resolver 函數告訴PyYAML所有未標記的形如 XdY 的普通標量具有顯式標簽 !dice,如下所示:
>>> import re>>> pattern = re.compile(r’^d+dd+$’)>>> yaml.add_implicit_resolver(’!dice’, pattern)
現在,在定義 Dice 對象的時候可以不使用標簽了,如下所示:
>>> print(yaml.dump({’treasure’: Dice(10, 20)})){treasure: 10d20}>>> print(yaml.load(’damage: 5d10’)){’damage’: Dice(5, 10)}
當將一個對象標記為安全的時候,在反序列化這樣的對象時只能使用 safe_load 或 safe_load_all 方法,否則會報錯,如下所示:
>>> 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 方法會報錯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語法
這一部分將介紹最常見的YAML結構以及相應的Python對象。
文檔
YAML流是零個或多個YAML文檔的集合??盏腨AML流不包含YAML文檔。YAML文檔間用文檔開始標記 --- 進行分隔。YAML文檔可以包含一個可選的文檔結束標記 ... 。如果流中只有一個文檔,那么可以不使用文檔開始標記。包含文檔開始標記的文檔可以稱為 顯式文檔 ,不包含文檔開始標記的文檔可以稱為 隱式文檔。
下面是一個隱式文檔:
- Multimedia- Internet- Education
下面是一個顯式文檔:
---- Afterstep- CTWM- Oroborus...
下面是一個包含多個文檔的YAML流:
---- Employee- Manager- CEO- CTO---- Student---- C- C# # YAML中使用‘#’ 來表示注釋(‘#’前面要有一個空格)- C++- Cold Fusion
塊序列
在塊內容中,使用破折號(dash) - 后跟一個空格(Space)來表示序列中的項。
下面是一個包含塊序列的文檔:
- id- name- age
上述文檔表示的一個如下的Python對象:
[’id’, ’name’, ’age’]
塊序列是可以嵌套的:
-- Python- Ruby- JavaScript- PHP-- Unix- Linux- Windows
上述文檔表示如下的Python對象:
[[’Python’, ’Ruby’, ’JavaScript’, ’PHP’], [’Unix’, ’Linux’, ’Windows’]]
在嵌套的塊序列中,內層的序列可以直接從當前行開始而不必從新的一行開始,如下所示:
- - Python- Ruby- JavaScript- PHP- - Unix- Linux- Windows
塊序列中可以嵌套在塊映射之中,在這種情況下,塊序列不需要縮進,如下所示:
Programing Languages:- Java- Swift- C++- GoOperation System:- Unix- Linux- Windows- OSX
上述文檔表示如下的Python對象:
{’Programing Languages’: [’Java’, ’Swift’, ’C++’, ’Go’], ’Operation System’: [’Unix’, ’Linux’, ’Windows’]}
塊映射
塊內容中,使用冒號 : 后跟一個空格來分隔映射中的鍵和值。
name: bobage: 28gender: Male
上述文檔表示如下的Python對象:
{’name’: ’bob’, ’age’: 28, ’gender’: ’Male’}
復雜的鍵使用問號 ? 后跟一個空格來表示,如下所示:
? !!python/tuple [0, 0]: Start? !!python/tuple [3, 5]: End
上述文檔表示如下的Python 對象:
{(0, 0): ’Start’, (3, 5): ’End’}
塊映射是可以嵌套的,如下所示:
Employee: Job_title: Employee Salary: 5000 Annual Leave: 10Manager: Job_title: Manager Salary: 8000 Annual Leave: 15
上述文檔表示如下的Python對象:
{’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對象:
[{’name’: ’PyYAML’, ’status’: 4, ’license’: ’MIT’, ’language’: ’Python’},{’name’: ’PySyck’, ’status’: 5, ’license’: ’BSD’, ’language’: ’Python’}]
流集合
YAML中流集合的語法與Python中列表和字典結構的語法很像,如下所示:
{ str: [15, 17], con: [16, 16], dex: [17, 18], wis: [16, 16], int: [10, 13], chr: [5, 8] }
上述文檔表示如下的Python對象:
{’dex’: [17, 18], ’int’: [10, 13], ’chr’: [5, 8], ’wis’: [16, 16], ’str’: [15, 17], ’con’: [16, 16]}
標量
YAML中的標量共有5中樣式,其中塊標量有兩種樣式:
文字樣式(literal style)
折疊樣式(folded style)
流標量有三種樣式:
普通樣式(plain style)
單引號樣式(single-quoted style)
雙引號樣式(double-quoted style)
這五種樣式的示例如下:
plain: Hello Worldsingle-quoted: ’所有內容都會原樣輸出’double-quoted: '需要用反斜杠轉移特殊字符'literal: |每一行都會包含換行符中間的每一個空行都會用換行符代替folded: >除過最后一行的換行符會保留其他行末尾的換行符都會使用一個空格代替中間的空行將會使用一個換行符代替
上述文檔表示如下的Python對象:
{’plain’: ’Hello World’,’single-quoted’: ’所有內容都會原樣輸出’,’double-quoted’: ’需要用反斜杠轉移特殊字符’,’literal’: ’每一行n都會n包含換行符n中間的每一個空行nn都會用換行符代替n’,’folded’: ’除過最后一行的 換行符 會保留 其他行末尾的換行符 都會使用一個空格代替 中間的空行n將會使用一個換行符代替n’}
每種樣式都有其特點。普通標量不使用指示符來表示其開始和結束,因此它是最受限制的樣式。普通標量自然適用于表示參數和屬性的名稱
使用單引號標量,可以表示不包含特殊字符的任何值。單引號標量不存在轉義,除非是一對相鄰的引號 ’’ 被單引號所替換”。
雙引號是最強大的樣式,也是惟一可以表示任何標量值的樣式。雙引號標量內的字符允許轉義。使用轉義序列 x* 和 u*** ,可以表達任何ASCII或Unicode字符。
塊標量樣式有兩種:文字樣式和折疊樣式。文字樣式是最適合于大型文本塊(如源代碼)的樣式。折疊樣式類似于文字樣式,但是兩個相鄰的非空行中間的換行符會被替換成一個空格從而變成一行。
別名
使用YAML可以表示任何類圖結構的對象。如果希望從文檔的不同部分引用相同的對象,則需要使用錨和別名。
其中,錨用 & 表示,別名用 * 表示。下面的例子將會演示錨和別名的使用:
emp1: &A name: bob age: 28 gender: Maleemp2: *A
上述文檔表示如下的Python對象:
{’emp1’: {’name’: ’bob’, ’age’: 28, ’gender’: ’Male’},’emp2’: {’name’: ’bob’, ’age’: 28, ’gender’: ’Male’}}
PyYAML現在已經支持遞歸對象,下面的文檔表示一個Python的列表,這個列表的元素是這個列表自身。
&A [ *A ]
標簽
標簽用來標識節點的數據類型。標準的YAML標簽的定義可以參考該文檔:
http://yaml.org/type/index.html
標簽可以是隱式地,如下所示:
boolen: trueinteger: 3float: 3.14
上述文檔表示如下的Python對象:
{’boolean’: True, ’integer’: 3, ’float’: 3.14}
標簽也可以是顯式的,如下所示:
boolean: !!bool 'true'integer: !!int '3'float: !!float '3.14'
上述文檔表示如下的Python對象:
{’boolean’: True, ’integer’: 3, ’float’: 3.14}
沒有顯式定義標簽的普通標量受制于隱式標簽解析。隱式標簽解析根據一組正則表達式檢查標量值,如果其中一個匹配,則為標量分配相應的標記。PyYAML允許應用程序添加自定義隱式標簽解析器。
YAML標簽和Python3 對象
YAML 標簽 Python對象 標準的YAML標簽 !!null None !!bool bool !!int int !!float float !!binary bytes !!timestamp datetime.datetime !!omap, !!pairs 元素為一個二元組的list !!set set !!str str !!seq list !!map dict Python的特殊標簽 !!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 復雜的Python標簽 !!python/name:module.name module.name !!python/module:package.module package.module !!python/object:module.cls module.cls 的實例 !!python/object/new:module.cls module.cls 的實例 !!python/object/apply:module.func 方法 func(...)的返回值字符串轉換
在Python3中,str 類型的對象將被轉變成使用標簽 !!str 標識的標量;bytes 類型的對象將被轉變成使用標簽 !!binary 標識的標量。為了考慮兼容性,標簽 !!python/str 和 !!python/unicode 仍然可以使用,被其標識的標量將被轉變成 str 類型的對象。
名稱和模塊
要表示靜態的Python對象,如函數和類,可以使用復雜的標簽Python !!python/name 。下面的例子演示了如何表示yaml模塊中的dump方法:
!!python/name:yaml.dump
類似的,模塊可以使用標簽 !!python/module :
!!python/module.yaml
對象
任何 pickleable 對象都可以使用標簽 !!python/object 來序列化:
!!python/object:module.Class { attribute: value, ... }
為了支持 pickle 協議,PyYAML提供了兩個附加的標簽
!!python/object/new:module.Class 和 !!python/object/apply:module.function
這兩個標簽的使用方法如下:
!!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說明就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。
相關文章: