python - `pyyaml` 可以 't parse ` pydantic ` object if ` Typing` 模块被使用

标签 python pydantic pyyaml

首先我要说的是,我想在 pydantic 存储库中打开一个问题。一旦我开始橡皮鸭调试,我就得出结论,实际上是 pyyaml 无法正常工作,但我不再那么确定了。

from dataclasses import dataclass
from functools import partial
from typing import List, Type

import yaml
from pydantic import BaseModel

yaml_input = """
!Foo
name: foo
bar:
    - !Bar
      name: bar
  """


def get_loader():
    loader = yaml.SafeLoader
    for tag_name, tag_constructor in tag_model_map.items():
        loader.add_constructor(tag_name, tag_constructor)
    return loader


def dynamic_constructor_mapping(model_class: Type[BaseModel], loader: yaml.SafeLoader,
                        node: yaml.nodes.MappingNode) -> BaseModel:
    return model_class(**loader.construct_mapping(node))


def get_constructor_for_mapping(model_class: Type[BaseModel]):
    return partial(dynamic_constructor_mapping, model_class)


class Bar(BaseModel):
    name: str


class Foo1(BaseModel):
    name: str
    bar: list


class Foo2(BaseModel):
    name: str
    bar: List


class Foo3(BaseModel):
    name: str
    bar: List[Bar]


@dataclass
class Foo4:
    name: str
    bar: List[Bar]


foos = [Foo1, Foo2, Foo3, Foo4]

for foo_cls in foos:
    tag_model_map = {
        "!Foo": get_constructor_for_mapping(foo_cls),
        "!Bar": get_constructor_for_mapping(Bar),
    }
    print(f"{foo_cls.__qualname__} loaded {yaml.load(yaml_input, Loader=get_loader())}")

打印内容

Foo1 loaded name='foo' bar=[Bar(name='bar')]
Foo2 loaded name='foo' bar=[]
Foo3 loaded name='foo' bar=[]
Foo4 loaded Foo4(name='foo', bar=[Bar(name='bar')])
  • 如果在静态类型中使用 list,则可以正确解析 pydantic 对象列表
  • 如果在静态类型中使用 List,则pydantic 对象列表无法正确解析
  • 如果在静态类型中使用 List[Bar]无法正确解析 pydantic 对象列表
  • dataclass 对象列表始终能够正确解析

构造函数似乎在所有示例中都返回了正确的对象,因此我不明白问题出在哪里。

pydantic==1.8.2
Python 3.8.10 

最佳答案

我遇到了和你一样的问题。

为我解决这个问题的方法是在construct_mapping 方法中将deep 设置为true。

示例:

fields = loader.construct_mapping(node, deep=True)

关于python - `pyyaml` 可以 't parse ` pydantic ` object if ` Typing` 模块被使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72126460/

相关文章:

python - 添加按钮未显示在 Django 教程 02 中

python - 如何根据另一列 B 的值替换 pandas 数据框列 A 的值

python - Django ContentFile() 意外空行 (django.core.files.base)

python - 使用 Pydantic 将每个字段设为可选

python-3.x - PyYAML 转储没有标签的 Python 对象

python - SqlAlchemy 不接受 DateTime 列中的 datetime.datetime.now 值

python - 唯一约束验证的最佳实践

python - 将 Pydantic 模型传递给另一个模型时复制

python - 如何处理 PyYaml 中的标签/类向后兼容性?

python - 解析 YAML,返回行号