pydantic学习与使用-5.dataclasses 数据类的学习使用
前言
python3.7 的新特性 dataclass,dataclass是指“一个带有默认值的可变的namedtuple”,广义的定义就是有一个类,它的属性均可公开访问。
dataclass简介
dataclass 的属性可以带有默认值并能被修改,而且类中含有与这些属性相关的类方法,那么这个类就可以称为dataclass,
再通俗点讲,dataclass就是一个含有数据及操作数据方法的容器。
- 相比普通class,dataclass通常不包含私有属性,数据可以直接访问
- dataclass的repr方法通常有固定格式,会打印出类型名以及属性名和它的值
- dataclass拥有__eq__和__hash__魔法方法
- dataclass有着模式单一固定的构造方式,或是需要重载运算符,而普通class通常无需这些工作
如果用的python3.6版本,需先安装dataclasses模块,python3.7以上版本已经自带了
pip install dataclasses==0.8
如果已经安装过pydantic包,dataclasses模块就已经一起装好了。
简单示例
dataclasses 数据类简单示例
from dataclasses import dataclass
from typing import List
@dataclass
class User:
"""用户数据类"""
name: str
age: int
friends: List[int]
user = User(name="yo yo", age=20, friends=[2, 3, 4])
print(user) # User(name='yo yo', age=20, friends=[2, 3, 4])
print(user.name) # yo yo
print(user.age) # 20
print(user.friends) # [2, 3, 4]
dataclass 继承的使用, 可以把前面的User 当成一个父类,子类继承后可以覆盖父类的属性
from dataclasses import dataclass
from typing import List
@dataclass
class User:
"""用户数据类"""
name: str
age: int
friends: List[int]
@dataclass
class Sun(User):
"""子类"""
name: str
age: str
friends: List[int]
a = Sun(name='yo', age='22', friends=[])
print(a)
pydantic 中使用 dataclasses
如果您不想使用pydantic 的 BaseModel 模块,您可以在标准数据类上获得相同的数据验证(在 python 3.7 中引入)。
数据类在 python 3.6 中需下载第三方包 dataclasses 工作。
from datetime import datetime
from pydantic.dataclasses import dataclass
@dataclass
class User:
id: int
name: str = 'John Doe'
signup_ts: datetime = None
user = User(id='42', signup_ts='2032-06-21T12:00')
print(user)
#> User(id=42, name='John Doe', signup_ts=datetime.datetime(2032, 6, 21, 12, 0))
pydantic.dataclasses.dataclass
是dataclasses.dataclass with validation
的替代品, 而不是pydantic.BaseModel
的替代品(在初始化挂钩的工作方式上有一点不同)
在某些情况下,将pydanticis.BaseModel
子类化是更好的选择.
您可以使用所有标准的 pydantic
字段类型,生成的数据类将与标准库 dataclass
装饰器创建的数据类相同。
可以通过 访问底层模型及其模式__pydantic_model__
。此外,需要 a 的字段default_factory
可以由 a 指定dataclasses.field
。
import dataclasses
from typing import List, Optional
from pydantic import Field
from pydantic.dataclasses import dataclass
@dataclass
class User:
id: int
name: str = 'John Doe'
friends: List[int] = dataclasses.field(default_factory=lambda: [0])
age: Optional[int] = dataclasses.field(
default=None,
metadata=dict(title='The age of the user', description='do not lie!')
)
height: Optional[int] = Field(None, title='The height in cm', ge=50, le=300)
user = User(id='42')
print(user.__pydantic_model__.schema())
"""
{
'title': 'User',
'type': 'object',
'properties': {
'id': {'title': 'Id', 'type': 'integer'},
'name': {
'title': 'Name',
'default': 'John Doe',
'type': 'string',
},
'friends': {
'title': 'Friends',
'type': 'array',
'items': {'type': 'integer'},
},
'age': {
'title': 'The age of the user',
'description': 'do not lie!',
'type': 'integer',
},
'height': {
'title': 'The height in cm',
'minimum': 50,
'maximum': 300,
'type': 'integer',
},
},
'required': ['id'],
}
"""
pydantic.dataclasses.dataclass的参数与标准装饰器相同,除了一个额外的关键字参数config与Config具有相同的含义。
嵌套数据类
数据类和普通模型都支持嵌套数据类。
from pydantic import AnyUrl
from pydantic.dataclasses import dataclass
@dataclass
class NavbarButton:
href: AnyUrl
@dataclass
class Navbar:
button: NavbarButton
navbar = Navbar(button=('https://example.com',))
print(navbar)
#> Navbar(button=NavbarButton(href=AnyUrl('https://example.com', scheme='https',
#> host='example.com', tld='com', host_type='domain')))
json 转储
Pydantic数据类没有.json()功能。要将它们转储为 JSON,您需要使用pydantic_encoder以下内容:
import dataclasses
import json
from typing import List
from pydantic.dataclasses import dataclass
from pydantic.json import pydantic_encoder
@dataclass
class User:
id: int
name: str = 'John Doe'
friends: List[int] = dataclasses.field(default_factory=lambda: [0])
user = User(id='42')
print(json.dumps(user, indent=4, default=pydantic_encoder))
"""
{
"id": 42,
"name": "John Doe",
"friends": [
0
]
}
"""