Python中JSON數(shù)據(jù)驗(yàn)證的三種專業(yè)級(jí)方案
第一章:揭秘Python中JSON數(shù)據(jù)驗(yàn)證的3大核心方案:你還在用if判斷?
在現(xiàn)代Web開(kāi)發(fā)中,JSON已成為數(shù)據(jù)交換的事實(shí)標(biāo)準(zhǔn)。面對(duì)復(fù)雜嵌套的數(shù)據(jù)結(jié)構(gòu),僅靠傳統(tǒng)的 if-else 判斷已難以保障數(shù)據(jù)的完整性與安全性。以下是三種專業(yè)級(jí)的Python JSON驗(yàn)證方案,助你告別繁瑣的手動(dòng)校驗(yàn)。
使用jsonschema進(jìn)行聲明式驗(yàn)證
jsonschema 是Python中最流行的JSON驗(yàn)證庫(kù),支持完整的JSON Schema規(guī)范。通過(guò)定義模式規(guī)則,自動(dòng)校驗(yàn)數(shù)據(jù)結(jié)構(gòu)。
# 安裝依賴: pip install jsonschema
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number", "minimum": 0}
},
"required": ["name"]
}
data = {"name": "Alice", "age": 25}
try:
validate(instance=data, schema=schema)
print("數(shù)據(jù)合法")
except ValidationError as e:
print("驗(yàn)證失敗:", e.message)
利用Pydantic實(shí)現(xiàn)類型安全的模型校驗(yàn)
Pydantic結(jié)合了類型提示與運(yùn)行時(shí)驗(yàn)證,廣泛應(yīng)用于FastAPI等現(xiàn)代框架中。
# 安裝: pip install pydantic
from pydantic import BaseModel, ValidationError
class User(BaseModel):
name: str
age: int = 0
try:
user = User(name="Bob", age=30)
print(user.model_dump())
except ValidationError as e:
print(e.json())
借助voluptuous構(gòu)建輕量級(jí)驗(yàn)證流程
Voluptuous適合配置文件或簡(jiǎn)單API接口的數(shù)據(jù)校驗(yàn),語(yǔ)法簡(jiǎn)潔直觀。
- 定義規(guī)則如同編寫(xiě)字典結(jié)構(gòu)
- 支持自定義驗(yàn)證函數(shù)
- 錯(cuò)誤信息清晰可讀
| 方案 | 適用場(chǎng)景 | 學(xué)習(xí)成本 |
|---|---|---|
| jsonschema | 復(fù)雜嵌套結(jié)構(gòu) | 中 |
| Pydantic | API開(kāi)發(fā)、類型安全 | 低 |
| Voluptuous | 配置校驗(yàn)、輕量項(xiàng)目 | 低 |
第二章:基于條件語(yǔ)句的傳統(tǒng)驗(yàn)證方法
2.1 理解JSON結(jié)構(gòu)與手動(dòng)校驗(yàn)邏輯
在構(gòu)建可靠的數(shù)據(jù)交互系統(tǒng)時(shí),理解 JSON 的基本結(jié)構(gòu)是首要步驟。一個(gè)合法的 JSON 對(duì)象由鍵值對(duì)組成,支持字符串、數(shù)字、布爾值、數(shù)組、嵌套對(duì)象和 null 類型。
常見(jiàn) JSON 結(jié)構(gòu)示例
{
"id": 1,
"name": "Alice",
"active": true,
"tags": ["user", "admin"],
"profile": {
"email": "alice@example.com",
"age": 30
}
}
該結(jié)構(gòu)展示了典型的用戶數(shù)據(jù)模型,包含基本類型與嵌套對(duì)象。字段 `tags` 使用數(shù)組存儲(chǔ)多標(biāo)簽,`profile` 實(shí)現(xiàn)信息分組。
手動(dòng)校驗(yàn)的關(guān)鍵邏輯
- 驗(yàn)證字段是否存在(如必填字段
id和name) - 檢查數(shù)據(jù)類型是否匹配(如
active應(yīng)為布爾型) - 遞歸遍歷嵌套結(jié)構(gòu)以確保深層字段合規(guī)
- 對(duì)數(shù)組元素逐一校驗(yàn)類型與格式
2.2 使用if-else鏈進(jìn)行字段存在性檢查
在處理結(jié)構(gòu)化數(shù)據(jù)時(shí),字段的可選性常導(dǎo)致運(yùn)行時(shí)異常。使用 `if-else` 鏈?zhǔn)且环N基礎(chǔ)但有效的字段存在性檢查方式,尤其適用于嵌套層級(jí)較深的對(duì)象。
基本檢查邏輯
通過(guò)逐層判斷對(duì)象及其屬性是否存在,避免訪問(wèn)空引用:
if (user && user.profile && user.profile.address) {
console.log(user.profile.address.city);
} else {
console.log("地址信息缺失");
}
上述代碼確保每級(jí)屬性均存在后再訪問(wèn)下一級(jí)。`user`、`profile` 和 `address` 依次被驗(yàn)證,防止因任一環(huán)節(jié)為 `null` 或 `undefined` 而拋出錯(cuò)誤。
適用場(chǎng)景對(duì)比
- 適用于低層級(jí)嵌套結(jié)構(gòu)
- 兼容性好,無(wú)需現(xiàn)代語(yǔ)法支持
- 邏輯清晰,便于調(diào)試和維護(hù)
2.3 嵌套結(jié)構(gòu)中的類型與值驗(yàn)證實(shí)踐
在處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)時(shí),嵌套對(duì)象的類型與值驗(yàn)證至關(guān)重要。為確保數(shù)據(jù)完整性,需逐層校驗(yàn)字段類型與取值范圍。
驗(yàn)證策略設(shè)計(jì)
采用遞歸遍歷方式對(duì)嵌套結(jié)構(gòu)進(jìn)行深度校驗(yàn),結(jié)合類型斷言與條件判斷,確保每一層級(jí)的數(shù)據(jù)符合預(yù)定義模式。
func validateNested(v interface{}) error {
if v == nil {
return fmt.Errorf("value cannot be nil")
}
rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.Map:
for _, key := range rv.MapKeys() {
if err := validateNested(rv.MapIndex(key).Interface()); err != nil {
return err
}
}
case reflect.String:
if rv.Len() == 0 {
return fmt.Errorf("string field cannot be empty")
}
}
return nil
}
上述代碼通過(guò)反射機(jī)制識(shí)別數(shù)據(jù)類型:若為映射類型,則遞歸校驗(yàn)每個(gè)子項(xiàng);若為字符串,則驗(yàn)證非空。該方法可擴(kuò)展至數(shù)字范圍、數(shù)組長(zhǎng)度等更多約束場(chǎng)景。
- 支持多層嵌套結(jié)構(gòu)的深度驗(yàn)證
- 可定制化校驗(yàn)規(guī)則以適應(yīng)業(yè)務(wù)需求
2.4 錯(cuò)誤處理與多層級(jí)異常捕獲策略
在現(xiàn)代軟件系統(tǒng)中,健壯的錯(cuò)誤處理機(jī)制是保障服務(wù)穩(wěn)定性的核心。通過(guò)分層捕獲異常,可以精準(zhǔn)定位問(wèn)題并執(zhí)行相應(yīng)恢復(fù)邏輯。
異常分層設(shè)計(jì)原則
- 底層模塊拋出具體異常,攜帶上下文信息
- 中間層進(jìn)行異常轉(zhuǎn)換,屏蔽敏感細(xì)節(jié)
- 頂層統(tǒng)一攔截,返回用戶友好提示
多層級(jí)捕獲示例(Go)
func processData() error {
err := parseInput()
if err != nil {
return fmt.Errorf("input layer: %w", err)
}
return nil
}
// 調(diào)用時(shí)可逐層展開(kāi)錯(cuò)誤鏈
if err != nil {
var parseErr *ParseError
if errors.As(err, &parseErr) {
log.Printf("Parsing failed: %v", parseErr)
}
}
該模式利用 Go 的錯(cuò)誤包裝(%w)和 errors.As 實(shí)現(xiàn)類型斷言,支持跨層級(jí)的錯(cuò)誤溯源與分類處理,提升調(diào)試效率與系統(tǒng)可觀測(cè)性。
2.5 手動(dòng)驗(yàn)證的局限性與維護(hù)成本分析
在軟件交付流程中,手動(dòng)驗(yàn)證依賴人工執(zhí)行測(cè)試用例與環(huán)境檢查,隨著系統(tǒng)復(fù)雜度上升,其局限性愈發(fā)顯著。首先,人為操作易引入誤差,尤其在高頻部署場(chǎng)景下,遺漏關(guān)鍵驗(yàn)證步驟的風(fēng)險(xiǎn)顯著增加。
效率與可重復(fù)性問(wèn)題
手動(dòng)驗(yàn)證難以保證每次操作的一致性。例如,在微服務(wù)架構(gòu)中驗(yàn)證接口兼容性時(shí),需反復(fù)調(diào)用多個(gè)端點(diǎn):
curl -s http://api.service/v1/health | jq '.status' curl -s http://auth.service/v2/token?user=test | jq '.expires_in'
上述命令雖簡(jiǎn)單,但長(zhǎng)期依賴人工輸入易出錯(cuò),且無(wú)法自動(dòng)記錄執(zhí)行上下文。
維護(hù)成本量化
隨著業(yè)務(wù)增長(zhǎng),驗(yàn)證清單呈指數(shù)級(jí)擴(kuò)張。使用表格對(duì)比自動(dòng)化與手動(dòng)方式的長(zhǎng)期成本:
| 維度 | 手動(dòng)驗(yàn)證 | 自動(dòng)化方案 |
|---|---|---|
| 單次耗時(shí) | 30 分鐘 | 2 分鐘 |
| 年維護(hù)工時(shí) | 600 小時(shí) | 80 小時(shí) |
可見(jiàn),手動(dòng)方式在可持續(xù)性上處于明顯劣勢(shì)。
第三章:使用jsonschema實(shí)現(xiàn)標(biāo)準(zhǔn)化驗(yàn)證
3.1 JSON Schema規(guī)范入門(mén)與模式定義
核心概念與基本結(jié)構(gòu)
JSON Schema 是一種用于描述和驗(yàn)證 JSON 數(shù)據(jù)結(jié)構(gòu)的規(guī)范。它通過(guò)定義數(shù)據(jù)的類型、格式、約束等規(guī)則,確保數(shù)據(jù)的一致性與合法性。一個(gè)基礎(chǔ)的 Schema 包含 $schema 聲明版本、type 指定數(shù)據(jù)類型,以及 properties 定義字段。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number", "minimum": 0 }
},
"required": ["name"]
}
上述代碼定義了一個(gè)對(duì)象結(jié)構(gòu),要求包含字符串類型的 name 和非負(fù)數(shù)字類型的 age,其中 name 為必填項(xiàng)。
常用驗(yàn)證關(guān)鍵字
type:指定值的類型,如 string、number、object 等required:聲明哪些屬性必須存在minimum/maximum:限制數(shù)值范圍format:增強(qiáng)語(yǔ)義,如 email、date-time
3.2 集成jsonschema庫(kù)進(jìn)行高效校驗(yàn)
在現(xiàn)代API開(kāi)發(fā)中,確保JSON數(shù)據(jù)結(jié)構(gòu)的合法性至關(guān)重要。`jsonschema`庫(kù)為Python提供了符合IETF標(biāo)準(zhǔn)的JSON Schema校驗(yàn)?zāi)芰Γ軌蛱崆皵r截非法請(qǐng)求。
安裝與基礎(chǔ)使用
通過(guò)pip安裝庫(kù):
pip install jsonschema
該命令將引入核心校驗(yàn)?zāi)K,支持Draft 7及以下版本的Schema規(guī)范。
定義校驗(yàn)規(guī)則
使用字典結(jié)構(gòu)描述數(shù)據(jù)約束:
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number", "minimum": 0}
},
"required": ["name"]
}
此Schema要求輸入為對(duì)象,`name`字段必填且為字符串,`age`若存在則必須為非負(fù)數(shù)。
執(zhí)行數(shù)據(jù)校驗(yàn)
利用validate()函數(shù)進(jìn)行校驗(yàn):
from jsonschema import validate, ValidationError
try:
validate(instance={"name": "Alice", "age": 25}, schema=schema)
except ValidationError as e:
print(f"校驗(yàn)失敗: {e.message}")
當(dāng)數(shù)據(jù)不符合Schema時(shí),拋出ValidationError異常,攜帶具體錯(cuò)誤信息。
3.3 自定義校驗(yàn)規(guī)則與擴(kuò)展關(guān)鍵字應(yīng)用
在復(fù)雜業(yè)務(wù)場(chǎng)景中,內(nèi)置校驗(yàn)規(guī)則往往無(wú)法滿足需求,需引入自定義校驗(yàn)邏輯。通過(guò)擴(kuò)展關(guān)鍵字,可靈活實(shí)現(xiàn)字段間依賴、動(dòng)態(tài)條件判斷等高級(jí)校驗(yàn)。
注冊(cè)自定義校驗(yàn)器
以 Go 語(yǔ)言為例,使用 validator 庫(kù)注冊(cè)手機(jī)號(hào)格式校驗(yàn):
validate.RegisterValidation("mobile", func(fl validator.FieldLevel) bool {
mobile := fl.Field().String()
matched, _ := regexp.MatchString(`^1[3-9]\d{9}$`, mobile)
return matched
})
該函數(shù)注冊(cè)名為 mobile 的校驗(yàn)標(biāo)簽,通過(guò)正則驗(yàn)證中國(guó)大陸手機(jī)號(hào)格式。
應(yīng)用場(chǎng)景示例
- 用戶注冊(cè)時(shí)郵箱與手機(jī)至少填寫(xiě)一項(xiàng)
- 訂單金額大于0且不超過(guò)賬戶余額
- 日期范圍中“結(jié)束時(shí)間”不得早于“開(kāi)始時(shí)間”
第四章:利用Pydantic進(jìn)行現(xiàn)代化數(shù)據(jù)建模
4.1 Pydantic基礎(chǔ):模型定義與自動(dòng)類型轉(zhuǎn)換
Pydantic 是 Python 中用于數(shù)據(jù)解析和驗(yàn)證的強(qiáng)大庫(kù),其核心是通過(guò)繼承 `BaseModel` 定義數(shù)據(jù)模型,并實(shí)現(xiàn)自動(dòng)類型轉(zhuǎn)換。
模型定義示例
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
is_active: bool = True
user = User(name="Alice", age="25")
print(user.age) # 輸出: 25 (自動(dòng)轉(zhuǎn)為 int)
該代碼展示了 Pydantic 如何將字符串 `"25"` 自動(dòng)轉(zhuǎn)換為整型 `int`。字段聲明使用類型注解,構(gòu)造實(shí)例時(shí)會(huì)觸發(fā)類型轉(zhuǎn)換與驗(yàn)證流程。
常用內(nèi)置類型轉(zhuǎn)換
str→int,float: 數(shù)值字符串轉(zhuǎn)數(shù)字int,float→str: 支持反向轉(zhuǎn)換bool: "1", "true", "on", 非零數(shù)均視為 True
4.2 復(fù)雜嵌套與可選字段的優(yōu)雅處理
在現(xiàn)代 API 設(shè)計(jì)中,數(shù)據(jù)結(jié)構(gòu)常涉及多層嵌套與可選字段。若處理不當(dāng),易導(dǎo)致空指針異?;蚪馕鍪?。通過(guò)合理使用泛型與默認(rèn)值機(jī)制,可顯著提升代碼健壯性。
零值安全的結(jié)構(gòu)體設(shè)計(jì)
type User struct {
ID *int64 `json:"id,omitempty"`
Profile *Profile `json:"profile,omitempty"`
Metadata *Metadata `json:"metadata,omitempty"`
}
使用指針類型表示可選字段,配合 omitempty 標(biāo)簽實(shí)現(xiàn)序列化時(shí)自動(dòng)忽略空值,避免前端接收到 null 字段。
嵌套解析的防御性編程
- 訪問(wèn)前判空,防止運(yùn)行時(shí) panic
- 提供默認(rèn)值構(gòu)造函數(shù),如
NewUser() - 結(jié)合 JSON Schema 進(jìn)行預(yù)校驗(yàn)
4.3 數(shù)據(jù)清洗、默認(rèn)值與校驗(yàn)裝飾器實(shí)踐
在構(gòu)建穩(wěn)健的API服務(wù)時(shí),數(shù)據(jù)質(zhì)量是關(guān)鍵。使用校驗(yàn)裝飾器可集中處理輸入清洗與合法性判斷。
裝飾器實(shí)現(xiàn)字段校驗(yàn)
@validate_fields({
'email': {'required': True, 'format': 'email'},
'age': {'default': 18, 'min': 0, 'max': 120}
})
def create_user(data):
return save_to_db(data)
該裝飾器自動(dòng)注入默認(rèn)值(如 age=18),并對(duì) email 進(jìn)行格式校驗(yàn),拒絕非法輸入。
常見(jiàn)校驗(yàn)規(guī)則配置
| 字段 | 規(guī)則說(shuō)明 |
|---|---|
| 必填,符合郵箱正則 | |
| age | 非負(fù)整數(shù),默認(rèn)18,上限120 |
通過(guò)統(tǒng)一裝飾器封裝,提升代碼可維護(hù)性與數(shù)據(jù)安全性。
4.4 在FastAPI等框架中的典型應(yīng)用場(chǎng)景
異步數(shù)據(jù)處理與API響應(yīng)
在FastAPI中,利用其原生支持的異步特性,可高效處理I/O密集型任務(wù)。例如,在用戶注冊(cè)接口中并發(fā)執(zhí)行郵箱驗(yàn)證與數(shù)據(jù)庫(kù)寫(xiě)入:
@app.post("/register")
async def register_user(user: UserCreate):
# 異步保存用戶并發(fā)送確認(rèn)郵件
await save_to_db(user)
await send_confirmation_email(user.email)
return {"status": "registered"}
上述代碼通過(guò)await實(shí)現(xiàn)非阻塞調(diào)用,提升吞吐量。兩個(gè)協(xié)程任務(wù)依次提交至事件循環(huán),避免線程等待。
依賴注入與安全控制
FastAPI的依賴系統(tǒng)適用于統(tǒng)一認(rèn)證邏輯:
- 通過(guò)
Depends()注入JWT驗(yàn)證函數(shù) - 自動(dòng)攔截未授權(quán)請(qǐng)求并返回401狀態(tài)碼
- 實(shí)現(xiàn)細(xì)粒度權(quán)限控制(如RBAC)
第五章:總結(jié)與展望
技術(shù)演進(jìn)的實(shí)際影響
現(xiàn)代軟件架構(gòu)正快速向云原生和微服務(wù)轉(zhuǎn)型。以某金融企業(yè)為例,其核心交易系統(tǒng)從單體架構(gòu)遷移至基于 Kubernetes 的微服務(wù)架構(gòu)后,部署頻率提升 300%,故障恢復(fù)時(shí)間縮短至秒級(jí)。這一過(guò)程依賴于持續(xù)集成流水線的重構(gòu)與服務(wù)網(wǎng)格的引入。
- 使用 GitOps 模式管理集群狀態(tài),確保環(huán)境一致性
- 通過(guò) Prometheus + Grafana 實(shí)現(xiàn)全鏈路監(jiān)控
- 采用 OpenTelemetry 統(tǒng)一追蹤日志、指標(biāo)與鏈路數(shù)據(jù)
未來(lái)技術(shù)方向的實(shí)踐路徑
邊緣計(jì)算與 AI 推理的融合正在催生新型部署模式。例如,在智能制造場(chǎng)景中,工廠本地節(jié)點(diǎn)運(yùn)行輕量化模型進(jìn)行實(shí)時(shí)缺陷檢測(cè),同時(shí)將樣本上傳至中心平臺(tái)訓(xùn)練優(yōu)化全局模型。
// 示例:在邊緣節(jié)點(diǎn)部署的 Go 微服務(wù)片段
func handleInference(w http.ResponseWriter, r *http.Request) {
var req ImageRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid request", http.StatusBadRequest)
return
}
// 調(diào)用本地 ONNX Runtime 執(zhí)行推理
result, err := onnxModel.Predict(req.Data)
if err != nil {
http.Error(w, "inference failed", http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(result)
}
架構(gòu)彈性設(shè)計(jì)的關(guān)鍵考量
| 設(shè)計(jì)維度 | 當(dāng)前方案 | 演進(jìn)目標(biāo) |
|---|---|---|
| 服務(wù)發(fā)現(xiàn) | DNS + Sidecar | 基于 eBPF 的透明發(fā)現(xiàn) |
| 配置管理 | ConfigMap + Vault | 動(dòng)態(tài)策略引擎驅(qū)動(dòng) |
以上就是Python中JSON數(shù)據(jù)驗(yàn)證的三種專業(yè)級(jí)方案的詳細(xì)內(nèi)容,更多關(guān)于Python JSON數(shù)據(jù)驗(yàn)證方案的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實(shí)現(xiàn)文件助手中查看微信撤回消息
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)文件助手中查看微信撤回消息,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04
Python+pandas計(jì)算數(shù)據(jù)相關(guān)系數(shù)的實(shí)例
今天小編就為大家分享一篇Python+pandas計(jì)算數(shù)據(jù)相關(guān)系數(shù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
Python3實(shí)現(xiàn)發(fā)送郵件和發(fā)送短信驗(yàn)證碼功能
這篇文章主要介紹了Python3實(shí)現(xiàn)發(fā)送郵件和發(fā)送短信驗(yàn)證碼功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
如何基于Python實(shí)現(xiàn)一個(gè)慶祝國(guó)慶節(jié)的小程序
這篇文章主要介紹了如何基于Python實(shí)現(xiàn)一個(gè)慶祝國(guó)慶節(jié)的小程序,增加了互動(dòng)選擇祝福語(yǔ)、查詢信息、播放背景音樂(lè)及趣味小測(cè)驗(yàn)等功能,使用tkinter增強(qiáng)GUI,提升用戶互動(dòng)體驗(yàn),需要的朋友可以參考下2024-09-09
django報(bào)錯(cuò)設(shè)置auth User的解決
本文主要介紹了django報(bào)錯(cuò)設(shè)置auth User的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Python多進(jìn)程協(xié)作模擬實(shí)現(xiàn)流程
當(dāng)多個(gè)進(jìn)程使用同一份數(shù)據(jù)資源的時(shí)候,因?yàn)檫M(jìn)程的運(yùn)行沒(méi)有順序,運(yùn)行起來(lái)也無(wú)法控制,如果不加以干預(yù),往往會(huì)引發(fā)數(shù)據(jù)安全或順序混亂的問(wèn)題,所以要在多個(gè)進(jìn)程讀寫(xiě)共享數(shù)據(jù)資源的時(shí)候加以適當(dāng)?shù)牟呗?,?lái)保證數(shù)據(jù)的一致性問(wèn)題2023-01-01
詳解如何利用pandas進(jìn)行數(shù)據(jù)行轉(zhuǎn)列和列轉(zhuǎn)行
這篇文章主要為大家詳細(xì)介紹了如何利用pandas進(jìn)行數(shù)據(jù)行轉(zhuǎn)列和列轉(zhuǎn)行,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2007-02-02

