下面是一个演示该问题的最小示例。
第一个,进口:
from dataclasses import dataclass, field
from typing import List
import yaml
下一步,定义从yaml.YAMLObject
:派生的类
@dataclass
class Yaz(yaml.YAMLObject):
name: str
items: List[str] = field(default_factory=lambda: ['a', 'b', 'c'])
yaml_tag: str = u'!Yaz'
演示用法:
Yaz(name='Yazzzy') # >>> Yaz(name='Yazzzy', items=['a', 'b', 'c'], yaml_tag='!Yaz')
Yaz(name='Yazzzy', items=[]) # >>> Yaz(name='Yazzzy', items=[], yaml_tag='!Yaz')
但有时我想从YAML文件中实例化一个实例。模拟YAML文件:
yaml_str = """---
!Yaz
name: Yazzzy
"""
将YAML文件加载到实例中:
yaml.load(yaml_str, Loader=yaml.Loader) # ERROR!
最后一行产生以下错误:
AttributeError: 'Yaz' object has no attribute 'items'
有什么钩子我不见了吗?
提前感谢!
注意:我使用Python 3.8
和pyyaml 6.0
。
我建议您使用dataclass-wizard
来完成此任务。它附带了一个名为YAMLWizard
的助手Mixin类,您可以将其与pyyaml 6.0
一起使用。为了澄清,它确实使用pyyaml
来处理YAML数据。
下面是一个工作示例。注意,我继续删除了YAML对象中的yaml.YAMLObject
和相关标签,因为这已经不需要了。
我还没有在示例中展示这一点,但也可以使用相同的方法从YAML加载嵌套数据类模型。您可以在此处查看嵌套模型的示例。
from __future__ import annotations # can be removed in Python 3.9+
from dataclasses import dataclass, field
from dataclass_wizard import YAMLWizard
@dataclass
class Yaz(YAMLWizard):
name: str
items: list[str] = field(default_factory=lambda: ['a', 'b', 'c'])
Yaz(name='Yazzzy') # >>> Yaz(name='Yazzzy', items=['a', 'b', 'c'])
Yaz(name='Yazzzy', items=[]) # >>> Yaz(name='Yazzzy', items=[])
yaml_str = """---
name: Yazzzy
"""
yaz_object = Yaz.from_yaml(yaml_str)
print(yaz_object)
输出:
Yaz(name='Yazzzy', items=['a', 'b', 'c'])