0%

python | Pydantic 介绍

在看这个之前,请先看

插件

pycharm 上,安装 pydantic 插件,可以检测你的语法对不对。

使用

简单的来说,Pydantic 就是结合注解的一种解析行库。

首先,我们看一个简单的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime


class Score(BaseModel):
score: int = 100


class User(BaseModel):
id: int
name: str = "xxx"
score: Score = Score()
sign_ts: Optional[datetime] = None
friends: List[int] = []


external_data = {
"id": 123,
"name": "8765",
"sign_ts": "2022-12-22 12:22",
"friends": [123, "3"],
"score": {
"score": 90
}
}

user = User(**external_data)
print(user)

这个 user 的结构如下

python | @dataclass 进行对比,其可以通过 dict 还原对象。

这种用法在 Pydantic 叫做递归模性。

捕获异常 ValidationError

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pydantic import BaseModel, ValidationError
from typing import Optional, List
from datetime import datetime


class Score(BaseModel):
score: int = 100


class User(BaseModel):
id: int
name: str = "xxx"
score: Score = Score()
sign_ts: Optional[datetime] = None
friends: List[int] = []


try:
user = User(id=123, friends=[1, 2, "not number"])
except ValidationError as e:
print(e.json())

则输出

1
2
3
4
5
6
7
8
9
10
[
{
"loc": [
"friends",
2
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]

这里面说的非常清楚,即 friends 中下标 2 的值出了问题。

相关 API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from pydantic import BaseModel, ValidationError
from typing import Optional, List
from datetime import datetime
from pathlib import Path


class Score(BaseModel):
score: int = 100


class User(BaseModel):
id: int
name: str = "xxx"
score: Score = Score()
sign_ts: Optional[datetime] = None
friends: List[int] = []


user = User(id=123, friends=[1, 2])

print(user.dict())
print(user.json())
print(user.copy()) # 浅层 copy
exter_data = {"id": 123, "friends": [1, 2, 3]}
print(User.parse_obj(obj=exter_data)) # 解析
print(User.parse_raw('{"id": 123, "friends": [1, 2, 3]}')) # 解析原生字符串

# 解析文件
path = Path("./t.txt")
path.write_text('{"id": 123, "friends": [1, 2, 3]}')
print(User.parse_file('./t.txt'))

# 不校验数据直接使用,下面这个 id 是字符串
data = {"id": "123", "friends": [1, 2, 3]}
print(User.construct(**data))

print(User.__fields__.keys()) # 定义模型类的时候,所有字段都注明类型,字段顺序就不会乱
请我喝杯咖啡吧~