Sup*_*man 5 python class list pydantic
有没有办法从列表中设置 pydantic 模型?我尝试过这个,但它对我不起作用。如果 pydantic 无法做到这一点,如果我仍然需要类型验证和转换、约束等,那么最好的方法是什么?顺序在这里很重要。
from pydantic import BaseModel
from datetime import date
class User(BaseModel):
id: int
name = 'John Doe'
sex: str
money: float = None
dt: date
data = [1, 'Tike Myson', 'male', None, '2022-01-20']
user = User(*data)
>>> TypeError: __init__() takes exactly 1 positional argument (6 given)
Run Code Online (Sandbox Code Playgroud)
我在这里部分回答了它:使用非关键字参数(又名 *args)初始化 FastAPI BaseModel,但我将在这里提供更多动态选项。
您的案例存在问题,Pydantic 不维护所有字段的顺序(至少取决于您是否设置类型)。如果您指定类型,name那么这有效:
from pydantic import BaseModel
from datetime import date
class User(BaseModel):
id: int
name: str = 'John Doe'
sex: str
money: float = None
dt: date
def __init__(self, *args):
# Get a "list" of field names (or key view)
field_names = self.__fields__.keys()
# Combine the field names and args to a dict
# using the positions.
kwargs = dict(zip(field_names, args))
super().__init__(**kwargs)
data = [1, 'Tike Myson', 'male', None, '2022-01-20']
user = User(*data)
Run Code Online (Sandbox Code Playgroud)
这样做的缺点是不那么动态,但不存在顺序不理想的问题。
from pydantic import BaseModel
from datetime import date
class User(BaseModel):
id: int
name = 'John Doe'
sex: str
money: float = None
dt: date
field_names: ClassVar = ('id', 'name', 'sex', 'money', 'dt')
def __init__(self, *args):
# Combine the field names and args to a dict
# using the positions.
kwargs = dict(zip(self.field_names, args))
super().__init__(**kwargs)
data = [1, 'Tike Myson', 'male', None, '2022-01-20']
user = User(*data)
Run Code Online (Sandbox Code Playgroud)
__init__这与选项 2 类似,但有点简单(并且可重用性较差)。
from pydantic import BaseModel
from datetime import date
from typing import ClassVar
class User(BaseModel):
id: int
name = 'John Doe'
sex: str
money: float = None
dt: date
def __init__(self, id, name, sex, money, dt):
super().__init__(id=id, name=name, sex=sex, money=money, dt=dt)
data = [1, 'Tike Myson', 'male', None, '2022-01-20']
user = User(*data)
Run Code Online (Sandbox Code Playgroud)
另一种解决方案,但这不需要覆盖__init__. 然而,这在创建实例时需要更多代码:
from pydantic import BaseModel
from datetime import date
class User(BaseModel):
id: int
name = 'John Doe'
sex: str
money: float = None
dt: date
data = [1, 'Tike Myson', 'male', None, '2022-01-20']
# Combine the field names and data
field_names = ['id', 'name', 'sex', 'money', 'dt']
kwargs = dict(zip(field_names, data))
# Create an instance of User from a dict
user = User(**kwargs)
Run Code Online (Sandbox Code Playgroud)
如果您有多个地方需要它,请创建一个具有__init__重写的基类和子类。
| 归档时间: |
|
| 查看次数: |
3059 次 |
| 最近记录: |