python语法混乱_Python读写yaml排版混乱还丢失注释?我来告诉你解决办法!

Python使用Yaml

日常我们在使用Python读写Yaml时,都是使用推荐的Pyyaml模块。

安装: pip install pyyaml

导入: import yaml

至于操作,简直不要太简单... yaml只有两个方法load、dump,而且使用完全和json模块一样。但真的如此吗?显然不是...

Yaml安全告警

由于Yaml数据存在安全隐患,在使用pyyaml进行load时,会给出提示:

YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please

read https://msg.pyyaml.org/load for full details.

所以我们有以下方式解决:

添加Loader

info = yaml.load(data,Loader=yaml.SafeLoader)

使用语法糖

info = yaml.safe_load(data)

同时pyyaml支持多段yaml内容的文本读写功能,即load_all() dump_all()。当我们使用safe_load获取多节点yaml文件时,会出发yaml.composer.ComposerError的错误,所以更优雅的导入方式应该是:

import yaml

from yaml.composer import ComposerError

with open(file, 'r') as f:

data = f.read()

try:

return yaml.safe_load(data)

except ComposerError:

return yaml.safe_load_all(data)

要注意,load_all 返回的是一个generator。当然用了这么久yaml真的很少见多段yaml非要写在一个文件中的情况。

pyyaml的劣势

上面介绍的主要是pyyaml的读取功能,可是在pyyaml将读取后的内容进行二次写入时,你就会遇到很多的问题,比如:

原本的yaml文件字段顺序,被重新调整

所有的注释内容,全部丢失

顺序这个勉强还可以容忍,但是注释全部丢失真的是叔叔能忍,婶婶都忍不啊!让我们看一个yaml文件读写前后对比:

c2b6a29a3bac?utm_campaign=hugo

yaml读写前后对比

我们该如何解决这个问题呢?

ruamel.yaml

ruamel.yaml作为pyyaml的衍生版,在继承了传统pyyaml的基础上,增加了RoundTrip模式。在读取yaml的时候,将yaml转化为ordereddict。众所周知,collections中的ordereddict是一个有序的字典,这样就保证了我们yaml读写后的顺序一致。

安装: pip install ruamel.yaml

导入: from ruamel import yaml

来看看效果吧:

from ruamel import yaml

class YamlLoader:

def __init__(self, file):

self.file = file

def file_load(self):

with open(self.file, 'r', encoding='utf-8') as f:

data = f.read()

return yaml.load(data, Loader=yaml.RoundTripLoader)

def file_dump(self, data):

with open('newer_%s' % self.file, 'w',

encoding='utf-8') as f:

yaml.dump(data, f,

Dumper=yaml.RoundTripDumper)

yml = YamlLoader('single.yaml')

yaml_info = yml.file_load()

print(yaml_info)

yml.file_dump(yaml_info)

output:

ordereddict([('Users', [ordereddict([('Lilei', ordereddict([('age', 18), ('sex', 'male')]))]), ordereddict([('Hanmeimei', ordereddict([('age', 17), ('sex', 'female')]))])]), ('Code', ['Python', 'Java', 'Ruby'])])

c2b6a29a3bac?utm_campaign=hugo

ruamel.yaml效果

今天的分享就到这里,希望对大家有所帮助。如果有收获,记得转发+点再看支持下,谢谢。

The End

期待你关注我的公众号清风Python,如果你觉得不错,希望能动动手指转发给你身边的朋友们。

我的github地址:https://github.com/BreezePython

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值