首先我要说的是,我想在 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/