yaml介绍及pyyaml操作时格式化
Peng's Blog 只记录和技术相关的东西

yaml介绍及pyyaml操作时格式化

2018-01-21

简介

yaml 是当下非常流行的一种配置文件格式,它比JSON更方便易读。嗯,XML似乎已经凉了。

YAML是”YAML Ain’t a Markup Language”(YAML不是一种标记语言)的[递归缩写]。

详细的介绍请参考:

http://www.ruanyifeng.com/blog/2016/07/yaml.html

https://zh.wikipedia.org/wiki/YAML

demo

---
receipt:     Oz-Ware Purchase Invoice
date:        2012-08-06
customer:
    given:   Dorothy
    family:  Gale
   
items:
    - part_no:   A4786
      descrip:   Water Bucket (Filled)
      price:     1.47
      quantity:  4

    - part_no:   E1628
      descrip:   High Heeled "Ruby" Slippers
      size:      8
      price:     133.7
      quantity:  1

bill-to:  &id001
    street: | 
            123 Tornado Alley
            Suite 16
    city:   East Centerville
    state:  KS

以上来自维基百科,yaml词条的介绍。

python对yaml文件的操作

需要安装pyyaml依赖库

pip install pyyaml

读取yaml文件

yaml库里面提供了一个叫做 load() 的方法,使用姿势如下:

stream = open("xxx.yml")
doc = yaml.load(stream)

之后,可以像操作字典一样操作 doc 变量。

写入yaml文件

yaml库里面提供了一个叫做 dump() 的方法,使用姿势如下:

stream = open("xxx.yml","w")
test = {'xxx': 'xxxx', 'xxxx': ['xxxx']}
yaml.dump(test, stream)

dump操作是个大坑,后面有很多隐含的参数。其中比较有用的是 default_flow_style=False

带上这个就不会按照它默认的那种鬼格式生成了。

操作多个文件

所谓的多个文件是指这样的yaml文件:

---
allow:
- asds.*
group: xxx_group
---
allow:
- asds.*
group: xxx_group
---
allow:
- asds.*
group: xxx_group

多个文件用 - - - 来分来

这时候就需要用到 load_all(),和dump_all() 方法了。使用姿势类似。

格式化时需要的两个大坑

去掉 null

自动dump出来的yaml文件有个特别丑的地方,就是所有 None 类型的变量都会被识别成 null 然后写入到yaml文件。有些情况,我们并不想让null显示出来。

解决方法:

dump之前引入

def represent_none(self, _):
    return self.represent_scalar('tag:yaml.org,2002:null', '')


yaml.add_representer(type(None), represent_none)

yaml文件里,属性顺序的控制

group: xxx_group
allow: asds.*

这种文件,我们希望 group 在 allow 属性的上面。但是默认情况,yaml 并不会那么聪明,他会按照首字母的排序,把a放在g的前面。。这个很坑。

解决方法:

dump之前引入

class UnsortableList(list):
    def sort(self, *args, **kwargs):
        pass


class UnsortableOrderedDict(OrderedDict):
    def items(self, *args, **kwargs):
        return UnsortableList(OrderedDict.items(self, *args, **kwargs))

      
yaml.add_representer(UnsortableOrderedDict,yaml.representer.SafeRepresenter.represent_dict)
      
  
stream = open("xxx.yml","w")

# 在dump之前需要对读出来的对象进行操作,进行无序化
xx = UnsortableOrderedDict(xx)

dump(xx,stream)

这样,生成的 yaml 文件,就能按照我们想要的顺序进行写入了。

参考资料

  1. YAML 语言教程-阮一峰
  2. pyyaml官方文档
  3. https://stackoverflow.com/questions/37200150/can-i-dump-blank-instead-of-null-in-yaml-pyyaml?answertab=active#tab-top
  4. https://stackoverflow.com/questions/16782112/can-pyyaml-dump-dict-items-in-non-alphabetical-order

Similar Posts

Comments

评论功能暂停使用,如需跟作者讨论请联系底部的GitHub