pyyaml是否支持dataclass中的默认列表



下面是一个演示该问题的最小示例。

第一个,进口:

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.8pyyaml 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'])

最新更新