繁体   English   中英

从 Python 中的 YAML 创建自定义 class 的对象

[英]Create objects of custom class from YAML in Python

我有 Class 定义:

Class 定义

class Task(object):
    def __init__(self, name, *depends):
        self.__name    = name
        self.__depends = set(depends)

    @property
    def name(self):
        return self.__name

    @property
    def depends(self):
        return self.__depends

代码的 rest 使用如下示例定义:

a = Task("a", "b")
b = Task("b")

nodes = (a, b)

我试图通过在单独的 function 中解析data来动态创建这些对象,然后我创建所有对象:

Yaml文件

a:
  foo:
   - "bar"
  graph_dep:
  - "b"
b:
  foo:
   - "bar"

我相信我能够通过 function 创建Task class 的ab对象

def format_input(data):
    services = data.keys()
    holder = {Task(name=name) for name in services}
    return holder

q1:如何将它们组合起来以获得nodes object 并具有与使用示例定义相同的结果? q2:如何从graph_dep获取值并将它们添加到holder = {Task(name=name) for name in services}字符串中?

对不起Python中的新手问题:)

通常,如果不需要 YAML 的原始结构,则无需将其加载到原生 Python 类型中。 相反,您应该只将它们加载到 YAML 节点图中,然后从中加载您想要的本机结构:

import yaml

input = """
a:
  foo:
   - "bar"
  graph_dep:
  - "b"
b:
  foo:
   - "bar"
"""

class Task(object):
  def __init__(self, name, *depends):
    self.__name    = name
    self.__depends = set(depends)

  @property
  def name(self):
    return self.__name

  @property
  def depends(self):
    return self.__depends

  def __str__(self):
    return "Task({}, {})".format(self.__name, self.__depends)

def load_dependency_list(loader, node):
  for item in node.value:
    if item[0].value == "graph_dep":
      return loader.construct_sequence(item[1])
  return []

def load_tasks(loader, node):
  ret = ()
  for item in node.value:
    name = loader.construct_scalar(item[0])
    deplist = load_dependency_list(loader, item[1])
    ret += (Task(name, *deplist),)
  return ret

loader = yaml.SafeLoader(input)
nodes = load_tasks(loader, loader.get_single_node())
for node in nodes:
  print(node)

这段代码的作用是:

  • 通过get_single_node()获取YAML文件中单个文档的节点图
  • 在返回的根节点上,执行加载代码

load_tasksload_dependency_list处理 YAML 中的级别。 PyYAML 确实提供了将这些函数注册为构造函数的工具,但是只有在 YAML 输入中有标签时才有意义(例如--- !nodes作为第一行)。 没有标签,PyYAML 不能自动 map 构造函数,所以你需要自己实现构造过程。

在这种情况下, load_dependency_list构造包含在graph_dep中的列表或返回空列表,忽略 YAML 节点中的其他内容。 load_tasks遍历顶层项目,从每个项目构造Task object,并将它们连接成一个元组。

我在 output 的Task中添加了一个__str__方法。 output 是

Task(a, {'b'})
Task(b, set())

此代码没有任何保护措施,我建议您在访问 YAML 节点时检查正确的节点类型,以便在结构错误时用户收到良好的错误消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM