ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

pydantic模型

2022-06-15 18:06:59  阅读:249  来源: 互联网

标签:__ name default 模型 BaseModel import class pydantic


模型

  • pydantic中定义对象的主要方法是通过模型BaseModel
1.1基本模型
from pydantic import BaseModel

class User(BaseModel):
    id: int  # 整形、必须
    name = 'Jane Doe'  # 通过默认值推断类型为字符串,不是必须,因为提供有默认值

    class Config:
        max_anystr_length = 10
        error_msg_templates = {
            'value_error.any_str.max_length': 'max_length:{limit_value}',
        }  


user = User(id='123')
  • user.dict():返回字典
  • user.json():返回json串
  • user.copy():返回一个浅拷贝对象
  • User.parse_obj():使用字典初始化对象
  • User.parse_raw():使用json串初始化对象
  • User.parse_file():使用文件初始化对象
  • User.from_orm():从orm实例初始化对象
  • user.schema():返回一个字典,将模型表示为 JSON 架构
  • user.schema_json():返回 的 JSON 字符串表示形式
  • User.construct():用于在不运行验证的情况下创建模型的类方法
  • user.__fields_set__:初始化模型实例时设置的字段名称集合
  • user.__fields__:模型字段的字典
  • __config__:模型的配置类
1.2递归模型
from typing import List
from pydantic import BaseModel


class Foo(BaseModel):
    count: int
    size: float = None


class Bar(BaseModel):
    apple = 'x'
    banana = 'y'


class Spam(BaseModel):
    foo: Foo
    bars: List[Bar]


m = Spam(foo={'count': 4}, bars=[{'apple': 'x1'}, {'apple': 'x2'}])
1.3ORM模型
  • Pydantic模型可以从任意类实例创建,以支持映射到ORM对象的模型。
  • "Config"属性必须设置为 。orm_mode=True
  • 必须使用特殊构造函数来创建模型实例。from_orm
from typing import List
from pydantic import BaseModel, constr
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class BookOrm(Base):
    __tablename__ = 'companies'
    id = Column(Integer, primary_key=True, nullable=False)
    name= Column(String(20), index=True, nullable=False, unique=True)
    desc = Column(String(255), nullable=True, default='')


class BookModel(BaseModel):
    id: int
    name: constr(max_length=20)
    desc: constr(max_length=255)

    class Config:
        orm_mode = True


book_orm = BookOrm(
    id=1,
    name='格林童话',
    desc='《格林童话》是由德国语言学家雅各布·格林和威廉·格林兄弟收集、整理、加工完成的德国民间文学。《格林童话》里面约有200多个故事,大部分源自民间的口头传说,其中的《灰姑娘》《白雪公主》《小红帽》《青蛙王子》等童话故事较为闻名',
)

book_model = BookModel.from_orm(book_orm)
  • 递归ORM模型
    from typing import List
    from pydantic import BaseModel
    
    
    class BookCls:
        def __init__(self, *, name: str, desc: str):
            self.name = name
            self.desc = desc
    
    
    class AuthorCls:
        def __init__(self, *, name: str, age: float = None, books: List[BookCls]):
            self.name = name
            self.age = age
            self.books = books
    
    
    class Book(BaseModel):
        name: str
        desc: str
    
        class Config:
            orm_mode = True
    
    
    class Author(BaseModel):
        name: str
        age: float = None
        books: List[Book]
    
        class Config:
            orm_mode = True
    
    
    book1 = BookCls(name='平凡的世界', desc='《平凡的世界》以中国70年代中期到80年代中期十年间为背景,通过复杂的矛盾纠葛,以孙少安和孙少平两兄弟为中心,刻画了当时社会各阶层众多普通人的形象;劳动与爱情、挫折与追求、痛苦与欢乐、日常生活与巨大社会冲突纷繁地交织在一起,深刻地展示了普通人在大时代历史进程中所走过的艰难曲折的道路')
    book2 = BookCls(name='人生', desc='《人生》以改革时期陕北高原的城乡生活为时空背景,描写了高中毕业生高加林回到土地又离开土地,再回到土地这样人生的变化过程,构成了其故事构架。高加林同农村姑娘刘巧珍,城市姑娘黄亚萍之间的感情纠葛构成了故事发展的矛盾,也正是体现那种艰难选择的悲剧')
    moyan = AuthorCls(name='莫言', age=43, books=[book1, book2])
    moyan_model = Author.from_orm(moyan)
    print(moyan_model)
    
    # name='莫言' age=20.0 books=[Book(name='平凡的世界', desc='《平凡的世界》以中国70年代中期到80年代中期十年间为背景,通过复杂的矛盾纠葛,以孙少安和孙少平两兄弟为中心,刻画了当时社会各阶层众多普通人的形象;劳动与爱情、挫折与追求、痛苦与欢乐、日常生活与巨大社会冲突纷繁地交织在一起,深刻地展示了普通人在大时代历史进程中所走过的艰难曲折的道路'), Book(name='人生', desc='《人生》以改革时期陕北高原的城乡生活为时空背景,描写了高中毕业生高加林回到土地又离开土地,再回到土地这样人生的变化过程,构成了其故事构架。高加林同农村姑娘刘巧珍,城市姑娘黄亚萍之间的感情纠葛构成了故事发展的矛盾,也正是体现那种艰难选择的悲剧')]
    
1.4通用模型
  • Pydantic 支持创建通用模型,以便更轻松地重用通用模型结构。
from typing import Generic, TypeVar, Optional, List

from pydantic import BaseModel, validator, ValidationError
from pydantic.generics import GenericModel


# 定义泛型
DataT = TypeVar('DataT')


class Error(BaseModel):
    code: int
    message: str


class DataModel(BaseModel):
    numbers: List[int]
    people: List[str]


class Response(GenericModel, Generic[DataT]):
    data: Optional[DataT]  # data参数可以是任意类型
    error: Optional[Error]


data = DataModel(numbers=[1, 2, 3], people=[])
error = Error(code=404, message='Not found')

print(Response[int](data=1).dict())
print(Response[str](data='value').dict())
print(Response(data=data, error=error).dict())
1.5模型字段不允许修改
from pydantic import BaseModel


class FooBarModel(BaseModel):
    a: str
    b: dict

    class Config:
        allow_mutation = False


# 一旦数据被初始化就不允许修改 allow_mutation = False
foobar = FooBarModel(a='hello', b={'apple': 'pear'})

try:
    foobar.a = 'different'
except TypeError as e:
    print(e)
1.6模型字段顺序
  • 从 v1.0 开始,所有指定类型的字段(无论是仅指类型还是默认值)都将位于所有没有指定类型的字段之前
from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    a: int
    b = 2
    c: int = 1
    d = 0
    e: float


print(Model.__fields__.keys())
# dict_keys(['a', 'c', 'e', 'b', 'd'])  # 报错也是保持这个字段顺序
1.7必填字段
from pydantic import BaseModel, Field


class Model(BaseModel):
    a: int
    b: int = ...
    c: int = Field(...)
1.8必填可选字段
from typing import Optional
from pydantic import BaseModel, Field


class Model(BaseModel):
    a: Optional[int]  # 可选,默认值None
    b: Optional[int] = ...
    c: Optional[int] = Field(...)
1.9动态默认值
from uuid import UUID, uuid4
from pydantic import BaseModel, Field


class Model(BaseModel):
    uid: UUID = Field(default_factory=uuid4)
    updated: datetime = Field(default_factory=datetime.utcnow)
2.0自动排除属性
  • 以下划线开头的类变量和带ClassVar注释的属性将自动从模型中排除
from pydantic import BaseModel
from typing import ClassVar


class Model(BaseModel):
    id: int = 1
    _name: str = "jack"
    age: ClassVar = 23


print(Model.__fields__.keys())  # dict_keys(['id'])
m1 = Model()
print(m1._name)  # jack
print(m1.age)  # 23
2.1私有属性
  • 私有属性名称必须以下划线开头,以防止与模型字段冲突
  • _attr、__attr__两者都支持
from datetime import datetime
from pydantic import BaseModel, Field, PrivateAttr


class Model(BaseModel):
    updated: datetime = Field(default_factory=datetime.utcnow)
    # 私有属性需要更改或操作模型实例上的内部属性使用PrivateAttr而不是Field
    _updated: datetime = Field(default_factory=datetime.utcnow)
    _updated1: datetime = PrivateAttr(default_factory=datetime.utcnow)
    __updated2__: datetime = PrivateAttr(default_factory=datetime.utcnow)


print(m1.__private_attributes__)
# {'_updated1': ModelPrivateAttr(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>), '__updated2__': ModelPrivateAttr(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>)}
m1 = Model()
print(m1.updated)  # 2022-06-15 03:12:05.524165
print(m1._updated)  # default=PydanticUndefined default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720> extra={}
print(m1._updated1)  # 2022-06-15 03:12:05.524165
  • Config.underscore_attrs_are_private=True,则任何非 ClassVar 下划线属性都将被视为私有
class Model(BaseModel):
    updated: datetime = Field(default_factory=datetime.utcnow)
    # 私有属性需要更改或操作模型实例上的内部属性使用PrivateAttr而不是Field
    _updated: datetime = Field(default_factory=datetime.utcnow)
    _updated1: datetime = PrivateAttr(default_factory=datetime.utcnow)
    __updated2__: datetime = PrivateAttr(default_factory=datetime.utcnow)

    class Config:
        # 此时_updated也成为了私有属性
        underscore_attrs_are_private = True


print(m1.__private_attributes__)
# {'_updated': ModelPrivateAttr(default=FieldInfo(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>, extra={})), '_updated1': ModelPrivateAttr(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>), '__updated2__': ModelPrivateAttr(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>)}
2.2将数据解析为指定类型
  • parse_obj_as
from typing import List

from pydantic import BaseModel, parse_obj_as


class Item(BaseModel):
    id: int
    name: str


# `item_data` could come from an API call, eg., via something like:
# item_data = requests.get('https://my-api.com/items').json()
item_data = [{'id': 1, 'name': 'My Item'}]

items = parse_obj_as(List[Item], item_data)
print(items)
# [Item(id=1, name='My Item')]
2.3数据转换
from pydantic import BaseModel


class Model(BaseModel):
    a: int
    b: float
    c: str


print(Model(a=3.1415, b=' 2.72 ', c=123).dict())
# {'a': 3, 'b': 2.72, 'c': '123'}
2.4严格模式
from pydantic import BaseModel, conint, confloat, constr, ValidationError


class Model(BaseModel):
    a: conint(strict=True)
    b: confloat(strict=True)
    c: constr(strict=True)

try:
    print(Model(a=3.1415, b=' 2.72 ', c=123).dict())
except ValidationError as e:
    print(str(e))


'''
3 validation errors for Model
a
  value is not a valid integer (type=type_error.integer)
b
  value is not a valid float (type=type_error.float)
c
  str type expected (type=type_error.str)
'''

标签:__,name,default,模型,BaseModel,import,class,pydantic
来源: https://www.cnblogs.com/puffer/p/16377532.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有