> 總是怕收到亂七八糟的資料嗎?
> 總是因為型別錯誤爆錯誤訊息嗎?
> 今天就來認識 Pydantic!這個超好用的 Python 神器,讓你靠型別提示自動驗證資料、轉換型別,不再擔心資料問題!🚀
# 安裝 Pydantic
```bash
pip install pydantic
```
> [!Note]
> To read more about pydantic installation:
> {%preview https://docs.pydantic.dev/latest/install/ %}
# 基本使用
> 最常使用的當然就是定義一個 Model 啦
> 以下是我們的範例,試想我們現在有一個 class 叫 `User`
```python
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
signup_ts: str | None = None
friends: list[int] = []
user = User(id=123, name='John Doe', signup_ts="2024-05-01T12:00", friends=[1, 2, 3])
print(user)
print(user.id)
print(user.dict()) # 轉成 dictionary
```
# 自動型別轉換
> Pydantic 的自動型別轉換有多好用呢?
> 請看一下範例:
```python!
user = User(id='123', name='John Doe', signup_ts=None, friends=[1, '2', b'3'])
print(user)
```
```python
# id=123 name='John Doe' signup_ts=None friends=[1, 2, 3]
```
**Pydantic 會自動嘗試轉型!轉換失敗才會丟出 ValidationError。**
- '123' -> 123
- [1, '2', b'3'] -> [1, 2, 3]
# 驗證錯誤
> 如果不能自動轉換怎麼辦
```python=
from pydantic import BaseModel, ValidationError
class User(BaseModel):
id: int
name: str
signup_ts: str | None = None
friends: list[int] = []
try:
User(id='not-an-int', name='John Doe')
except ValidationError as e:
print(e)
```
```python
# 1 validation error for User
# id
# Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='not-an-int', input_type=str]
# For further information visit https://errors.pydantic.dev/2.11/v/int_parsing
```
# 使用巢狀 Model
> 有時候型別比較複雜就會使用到巢狀 Model
```python=
class Address(BaseModel):
street: str
city: str
class User(BaseModel):
name: str
address: Address
u = User(name="Alice", address={"street": "1st Street", "city": "Metropolis"})
print(u.address.street)
```
```python
# 1st Street
```
# Model 方法:dict、json、copy
```python=
from pydantic import BaseModel, ValidationError
class User(BaseModel):
id: int
name: str
user = User(id=123, name='John Doe')
print(user.model_dump()) # Dictionary
print(user.model_dump_json()) # JSON string
new_user = user.model_copy(update={'name': 'Jane Doe'})
print(new_user)
```
```python
# {'id': 123, 'name': 'John Doe'}
# {"id":123,"name":"John Doe"}
# id=123 name='Jane Doe'
```
> [!Note]
> The `dict` method is deprecated;
> The `json` method is deprecated;
> The `copy` method is deprecated;
# 欄位設定 (Field)
| 你想做的事 | 該怎麼用 |
|:------------------------|:---------------------------------------------|
| 讓欄位必填 | `Field(...)` |
| 設定預設值 | `Field(default_value)` |
| 設定數字範圍 | `gt=`, `ge=`, `lt=`, `le=` |
| 限制文字/列表長度 | `min_length=`, `max_length=`, `min_items=`, `max_items=` |
| 產生API文件說明 | `title=`, `description=` |
| 改名字接資料 | `alias="other_name"` |
| 排除欄位 | `exclude=True` |
| 動態預設值 | `default_factory=...` |
```python=
from pydantic import BaseModel, Field
class User(BaseModel):
id: int = Field(..., gt=0, lt=9999) # 必填且介於0-9999之間
name: str = Field(..., Harry) # 必填且default value是Harry
```
# 總結
有沒有深深體會Pydantic的好處呢?跟FastAPI更是完美搭配喔!