python操作yaml说明1. 安装PyYAML
pip install PyYAML
2. 加载yaml⽂件
直接使⽤yaml.load()函数
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('l'))
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 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": {
writelines方法的参数可以是"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('l', 'w').write(result)
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
补充知识:Python的PyYAML模块详解
简介
Python的PyYAML模块是Python的YAML解析器和⽣成器。
安装
简单安装
pip install pyyaml
从源码安装
下载源码包PyYAML-3. 并解压,在命令⾏下切换到解压后的包⽬录内并执⾏如下命令:
python setup.py install
如果想使⽤⽐纯Python版本更快的LibYAML绑定,需要先下载并安装LibYAML,然后在安装PyYAML的时候执⾏如下命令:
python setup.py --with-libyaml install
为了使⽤基于LibYAML的解析器和⽣成器,请使⽤ 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)
请注意,基于纯Python和基于LibYAML的YAML解析器和⽣成器之间有⼀些细微但并不真正重要的区别。
最常被问到的问题
为什么如下所⽰的YAML⽂档在反序列化后再序列化,得到的YAML⽂档的格式与原来不⼀样?
import yaml
document = """
a: 1
b:
c: 3
d: 4
"""
print(yaml.dump(yaml.load(document)))
其中,上⾯代码的输出为:
a: 1
b: {c: 3, d: 4}
关于这个问题,其实,尽管最后得到的YAML⽂档的样式与原来的⽂档的样式不⼀致,但是却是正确的结果。
因为PyYAML默认会根据⼀个集合中是否有嵌套的集合来决定⽤哪种格式表⽰这个集合。如果⼀个集合中嵌套有其他集合,那么会使⽤块样式来表⽰,否则会使⽤流样式来表⽰。
如果想要集合总是以块样式表⽰,可以将 dump() ⽅法的 default_flow_style 参数值设为 False ,如下所⽰:
print(yaml.dump(yaml.load(document), default_flow_style=False))
上⾯代码的输出为:
a: 1
b:
c: 3
d: 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('- Python\n- Ruby\n- 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
... der = gender
... def __repr__(self):
... return f"{self.__class__.__name__}(name={self.name!r}, age={self.age!r}, gender={der!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: SQA
name: Lex
salary: 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: SQA
name: Lex
salary: 8000
如果要将多个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
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论