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



我有类定义:

类定义

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

代码的其余部分使用这样的示例定义:

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

我试图通过在单独的函数中解析YAML来动态创建这个对象,该函数返回字典data,然后我创建所有对象:

Yaml文件

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

我相信我能够通过函数创建Task类的ab对象

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

q1:如何将它们组合以获得nodes对象,并获得与使用示例定义相同的结果?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就无法自动映射构造函数,因此您需要自己实现构建过程。

在这种情况下,load_dependency_list构造包含在graph_dep中的列表,或者返回空列表,忽略YAML节点中的其他内容。load_tasks对顶级项进行迭代,从每个项构造Task对象,并将它们连接到元组中。

我在Task中添加了一个__str__方法进行输出。输出为

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

这段代码没有任何保护措施,我建议在访问YAML节点时检查是否有正确的节点类型,这样,如果结构错误,用户就会收到一条好的错误消息。

最新更新