python - 在 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"
我相信我能够通过函数实现类的创建a
和b
对象Task
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)
这段代码的作用是:
- 通过获取 YAML 文件中单个文档的节点图
get_single_node()
- 在返回的根节点上,执行加载代码
load_tasks
并load_dependency_list
处理 YAML 中的级别。PyYAML 确实提供了将这些函数注册为构造函数的工具,但是只有在 YAML 输入中有标签时才有意义(例如--- !nodes
第一行)。如果没有标签,PyYAML 无法自动映射构造函数,因此需要您自己实现构造过程。
在这种情况下,load_dependency_list
构造包含在的列表graph_dep
或返回空列表,忽略 YAML 节点中的其他内容。load_tasks
遍历顶层项目,Task
从每个项目构造对象,并将它们连接成一个元组。
我添加了一个__str__
方法来Task
输出。输出是
Task(a, {'b'})
Task(b, set())
此代码没有任何保护措施,我建议您在访问 YAML 节点的任何地方检查正确的节点类型,以便在结构错误时用户收到良好的错误消息。
推荐阅读
- list - 取 List X 的最大值,并与 List Y 进行比较,找到 Y 中的最大值,使用 TCL 将其添加到新列表中
- unity3d - 是否可以在同一场景中为 2 个对象设置不同的重力?
- r - 关于错误:保护():保护堆栈溢出
- python - 根据条件从列表中删除数据帧
- typescript - .then(函数()在excel javascript中的含义
- javascript - 如何让元素按父级的高度在列中流动
- javascript - 如何在 Chrome 81+ 中忽略 Canvas 上的图像 exif 数据
- python - 在 QT for Python 中注册用户不活动?
- c# - WPF如何使用当前方法将绑定应用于视图
- javascript - onclick事件React后如何显示表单