• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于python:Python-读写和解析-YAML-文件格式

python 搞代码 3年前 (2022-02-20) 23次浏览 已收录 0个评论

指标

  • 读写API简略
  • 解析进去的数据结构易解决
  • 反对对象的序列化/反序列化

一个比拟好用的库是ruamel,须要装置一下:

pip install ruamel.yaml

而后代码中导入即可:

from ruamel.yaml import YAML

但导入的YAML是个类,真正用的时候,须要创立一个实例
yaml = YAML()

读写文件

筹备一个配置文件:

<code class="yaml">id: 100
name: "测试项目"
version: "3.1"
steps:
  - id: 18
    action: "Prepare"
    expects:
      - id: 238,
        result: GOOD
      - id: 239,
        result: PERFECT

代码中首先须要自行关上文件,而后把文件对象传给yaml实例:

        with open(conf_file) as f:
            data = yaml.load(f)
            for k, v in data.items():
                cls.handle_value(data, k, v)
        conf = yaml.load(f)

这里遍历load后的后果,而后通过业务函数(handle_value)自行处理的。

写和读的代码相似,还是自行用写模式关上文件,而后把一个dict/list嵌套构造的对象,传给dump函数即可

        with open(conf_file, 'w') as f:
            the_list = []
            for step in self.steps:
                the_list.append(step.to_dict())
            documents = yaml.dump(the_list, f)

例子里最外层对象是list,替换成dict也没有问题,总之须要是可枚举内容的对象。

序列化/反序列化

ruamel自身提供序列化/反序列化反对:

  • 首先,给须要序列化的类,加上yaml_object注解
  • 增加一个yaml_tag类属性,作为序列化前缀
  • 给这个类增加to_yaml和from_yaml两个类办法,别离解决序列化,和反序列化

示例如下:

@yaml_object(yaml)
class ScreenRect(dict):
    yaml_tag = u'!rect'

    def __init__(self, left: int = None, right: int = None, top: int = None, bottom: int = None):
        # super(ScreenRect, self).__init__([left, right, top, bottom])
        # self._inner_list = [left, right, top, bottom]
        self['l'] = left
        self['r'] = right
        self['t'] = top
        self['b'] = bottom

    @property
    def left(self):
        return self['l']

    @property
    def right(self):
        return self['r']

    @property
    def top(self):
        return self['t']

    @property
    def bottom(self):
        return self['b']

    def __str__(self):
        return 'l:{},  r:{},  t:{},  b:{}'.format(self.left, self.right, self.top, self.bottom)

    @classmethod
    def to_yaml(cls, representer, node):
        return representer.represent_scalar(cls.yaml_tag,
                                            'l:{}, r:{}, t:{}, b:{}'.format(node.left, node.right, node.top,
                                                                            node.bottom))
        # return {'l': self.left, 'r': self.right, 't': self.top, 'b': self.bottom}

    @classmethod
    def from_yaml(cls, constructor, node):
        splits = node.value.split(', ')
        # test = list(map(lambda x: x + '_sss', splits))
        v = list(map(lambda x: x[1], map(methodcaller("split", ":"), splits)))
        # print(v)
        return cls(left=int(v[0]), right=int(v[1]), top=int(v[2]), bottom=int(v[3]))

上例中,ScreenRect类是dict子类,但心愿序列化的时候,按特定格局生成字符串,所以在to_yaml中做了包装,几个property的定义只是为了当前ScreenRect类实例不便读写数据,并不是必须的。生成当前的数据,相似上面这个样子:

<code class="yaml">rect: !rect l:1415, r:1805, t:239, b:609

中文字符

一开始应用的时候,发现utf-8编码的配置文件无奈被读取,还认为ruamel不反对,起初发现是本人代码的问题,只须要关上文件的时候,指定编码就能够了:

with open(conf_file, encoding='utf-8') as f:

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于python:Python-读写和解析-YAML-文件格式

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址