最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實(shí)現(xiàn)將JSON數(shù)據(jù)轉(zhuǎn)換為數(shù)據(jù)類的方法匯總

 更新時(shí)間:2026年01月20日 09:26:54   作者:19970108018  
本文介紹了三種將JSON轉(zhuǎn)換為數(shù)據(jù)類的優(yōu)雅方案:基礎(chǔ)手動(dòng)轉(zhuǎn)換、進(jìn)階版自定義通用轉(zhuǎn)換函數(shù)和高級(jí)版使用pydantic,每種方法都有其適用場(chǎng)景和優(yōu)缺點(diǎn),建議在生產(chǎn)環(huán)境中使用pydantic,因?yàn)樗峁┝藦?qiáng)大的數(shù)據(jù)驗(yàn)證和自動(dòng)轉(zhuǎn)換功能,需要的朋友可以參考下

JSON 轉(zhuǎn)數(shù)據(jù)類的核心難點(diǎn)在于:JSON 只有基礎(chǔ)類型(字符串 / 數(shù)字 / 列表 / 字典),而數(shù)據(jù)類包含自定義結(jié)構(gòu)、嵌套類、非 JSON 原生類型(如datetime),需要自動(dòng)映射字段 + 類型轉(zhuǎn)換。下面從「基礎(chǔ)手動(dòng)轉(zhuǎn)換」到「生產(chǎn)級(jí)自動(dòng)轉(zhuǎn)換」給出 3 種優(yōu)雅方案,覆蓋不同場(chǎng)景需求。

前置準(zhǔn)備:定義測(cè)試數(shù)據(jù)類 + 測(cè)試 JSON

先復(fù)用之前的嵌套數(shù)據(jù)類,并準(zhǔn)備對(duì)應(yīng)的 JSON 字符串(模擬真實(shí)場(chǎng)景,包含嵌套、時(shí)間字符串等):

from dataclasses import dataclass, fields
import json
from datetime import datetime
from typing import Optional, Any

# 嵌套子數(shù)據(jù)類
@dataclass
class Address:
    province: str
    city: str
    detail: str = ""  # 可選字段

# 主數(shù)據(jù)類
@dataclass
class User:
    id: int
    name: str
    age: int
    register_time: datetime  # 非JSON原生類型(JSON中是字符串)
    address: Address  # 嵌套數(shù)據(jù)類
    tags: Optional[list[str]] = None  # 可選列表字段

# 測(cè)試JSON字符串(模擬接口返回/文件讀取的JSON)
test_json_str = """
{
  "id": 1001,
  "name": "張三",
  "age": 28,
  "register_time": "2026-01-19T10:30:00",
  "address": {
    "province": "浙江省",
    "city": "杭州市",
    "detail": "西湖區(qū)XX路"
  },
  "tags": ["VIP", "新用戶"]
}
"""

# 先將JSON字符串轉(zhuǎn)成Python字典(所有方案的前置步驟)
test_json_dict = json.loads(test_json_str)

方法 1:基礎(chǔ)版 - 手動(dòng)映射(簡(jiǎn)單場(chǎng)景,理解底層邏輯)

核心思路:先將 JSON 轉(zhuǎn)字典,再通過「關(guān)鍵字參數(shù)」直接實(shí)例化數(shù)據(jù)類,手動(dòng)處理嵌套類和非基礎(chǔ)類型。

代碼實(shí)現(xiàn):

# 步驟1:處理嵌套數(shù)據(jù)類(Address)
address_dict = test_json_dict.pop("address")  # 提取嵌套字典
address = Address(**address_dict)  # 字典轉(zhuǎn)嵌套數(shù)據(jù)類

# 步驟2:處理非基礎(chǔ)類型(datetime字符串轉(zhuǎn)datetime對(duì)象)
register_time_str = test_json_dict.pop("register_time")
register_time = datetime.fromisoformat(register_time_str)

# 步驟3:實(shí)例化主數(shù)據(jù)類(剩余字段直接傳參)
user = User(
    **test_json_dict,  # 展開剩余基礎(chǔ)字段(id/name/age/tags)
    address=address,
    register_time=register_time
)

# 驗(yàn)證結(jié)果
print(user)
# 輸出:User(id=1001, name='張三', age=28, register_time=datetime.datetime(2026, 1, 19, 10, 30), address=Address(province='浙江省', city='杭州市', detail='西湖區(qū)XX路'), tags=['VIP', '新用戶'])

關(guān)鍵解釋:

  • **address_dict:利用字典解包,將嵌套字典直接傳給Address的構(gòu)造函數(shù);
  • 手動(dòng)處理非基礎(chǔ)類型:JSON 中的時(shí)間字符串需要轉(zhuǎn)成datetime對(duì)象,這是 JSON 轉(zhuǎn)數(shù)據(jù)類的核心痛點(diǎn);
  • 優(yōu)點(diǎn):邏輯簡(jiǎn)單、易理解;缺點(diǎn):嵌套層級(jí) / 非基礎(chǔ)類型越多,代碼越繁瑣,復(fù)用性差。

方法 2:進(jìn)階版 - 自定義通用轉(zhuǎn)換函數(shù)(可擴(kuò)展,適配多數(shù)據(jù)類)

封裝一個(gè)通用函數(shù),遞歸處理嵌套數(shù)據(jù)類 + 自動(dòng)轉(zhuǎn)換常見非基礎(chǔ)類型,避免重復(fù)寫手動(dòng)映射代碼。

代碼實(shí)現(xiàn):

def json_dict_to_dataclass(data: dict, cls) -> Any:
    """
    通用JSON字典轉(zhuǎn)數(shù)據(jù)類函數(shù)(支持嵌套、datetime轉(zhuǎn)換)
    :param data: JSON解析后的字典
    :param cls: 目標(biāo)數(shù)據(jù)類(如User/Address)
    :return: 數(shù)據(jù)類實(shí)例
    """
    # 1. 遍歷數(shù)據(jù)類的所有字段
    field_map = {f.name: f for f in fields(cls)}
    init_kwargs = {}
    
    for field_name, field_type in field_map.items():
        # 跳過不存在的字段(可選字段)
        if field_name not in data:
            continue
        
        value = data[field_name]
        target_type = field_type.type
        
        # 2. 處理嵌套數(shù)據(jù)類(判斷是否是dataclass)
        if hasattr(target_type, "__dataclass_fields__"):
            init_kwargs[field_name] = json_dict_to_dataclass(value, target_type)
        # 3. 處理datetime類型(字符串轉(zhuǎn)datetime)
        elif target_type is datetime:
            init_kwargs[field_name] = datetime.fromisoformat(value)
        # 4. 基礎(chǔ)類型直接賦值
        else:
            init_kwargs[field_name] = value
    
    # 5. 實(shí)例化數(shù)據(jù)類
    return cls(**init_kwargs)

# 調(diào)用示例(一行搞定,支持嵌套)
user = json_dict_to_dataclass(test_json_dict, User)

# 驗(yàn)證結(jié)果
print(user)
print(user.address.city)  # 訪問嵌套字段:杭州市
print(user.register_time.year)  # 訪問datetime字段:2026

關(guān)鍵解釋:

  • fields(cls):獲取數(shù)據(jù)類的所有字段信息(名稱、類型),實(shí)現(xiàn)動(dòng)態(tài)映射;
  • 遞歸處理嵌套:如果字段類型是數(shù)據(jù)類(通過__dataclass_fields__判斷),遞歸調(diào)用函數(shù)轉(zhuǎn)換;
  • 可擴(kuò)展:如需支持date/UUID等類型,只需在函數(shù)中新增elif判斷即可;
  • 優(yōu)點(diǎn):通用、可復(fù)用,適配任意嵌套結(jié)構(gòu)的數(shù) - 據(jù)類;缺點(diǎn):需要自己維護(hù)類型轉(zhuǎn)換邏輯。

方法 3:高級(jí)版 - 使用pydantic(生產(chǎn)環(huán)境推薦,最優(yōu)雅)

pydantic是 Python 生態(tài)中處理數(shù)據(jù)驗(yàn)證 / 轉(zhuǎn)換的主流庫,原生支持 JSON 轉(zhuǎn)模型,自動(dòng)處理類型轉(zhuǎn)換、嵌套、可選字段,無需手動(dòng)寫轉(zhuǎn)換邏輯,是生產(chǎn)環(huán)境的最優(yōu)選擇。

前置依賴:

pip install pydantic

代碼實(shí)現(xiàn):

from pydantic import BaseModel
from datetime import datetime
from typing import Optional, List

# 替換原生dataclass為pydantic.BaseModel(語法幾乎一致,功能更強(qiáng))
class Address(BaseModel):
    province: str
    city: str
    detail: str = ""

class User(BaseModel):
    id: int
    name: str
    age: int
    register_time: datetime  # 自動(dòng)將ISO格式字符串轉(zhuǎn)datetime
    address: Address  # 自動(dòng)轉(zhuǎn)換嵌套模型
    tags: Optional[List[str]] = None

    # 可選:自定義類型轉(zhuǎn)換規(guī)則(如非ISO格式的時(shí)間字符串)
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat()  # 序列化時(shí)用,反序列化自動(dòng)識(shí)別
        }

# 方法1:JSON字符串直接轉(zhuǎn)模型(最優(yōu)雅)
user = User.parse_raw(test_json_str)

# 方法2:JSON字典轉(zhuǎn)模型(兼容已有字典)
# user = User(**test_json_dict)

# 驗(yàn)證結(jié)果
print(user)
# 輸出:id=1001 name='張三' age=28 register_time=datetime.datetime(2026, 1, 19, 10, 30) address=Address(province='浙江省', city='杭州市', detail='西湖區(qū)XX路') tags=['VIP', '新用戶']

# 便捷操作:模型轉(zhuǎn)字典/JSON(反向操作也支持)
print(user.dict())  # 轉(zhuǎn)字典
print(user.json(ensure_ascii=False, indent=2))  # 轉(zhuǎn)格式化JSON字符串

核心優(yōu)勢(shì):

  1. 零手動(dòng)轉(zhuǎn)換parse_raw()直接解析 JSON 字符串為模型,自動(dòng)處理嵌套、datetime等類型;
  2. 自動(dòng)數(shù)據(jù)驗(yàn)證:如果 JSON 數(shù)據(jù)類型錯(cuò)誤(如age傳字符串),會(huì)直接拋出清晰的異常,避免臟數(shù)據(jù);
  3. 靈活擴(kuò)展:支持自定義類型轉(zhuǎn)換器、可選字段、默認(rèn)值、數(shù)據(jù)校驗(yàn)規(guī)則(如age >= 0);
  4. 生態(tài)完善:兼容 FastAPI、Django 等框架,是生產(chǎn)環(huán)境處理數(shù)據(jù)的標(biāo)準(zhǔn)方案。

異常示例(數(shù)據(jù)驗(yàn)證):

如果 JSON 中age是字符串"28",pydantic會(huì)拋出明確錯(cuò)誤:

ValidationError: 1 validation error for User
age
  Input should be a valid integer, got a string [type=int_type, input_value='28', input_type=str]

總結(jié)

  1. 簡(jiǎn)單場(chǎng)景(少量字段 / 無嵌套) :用原生dataclass + 手動(dòng)映射,快速實(shí)現(xiàn),無需依賴第三方庫;
  2. 通用場(chǎng)景(多數(shù)據(jù)類 / 嵌套) :封裝自定義轉(zhuǎn)換函數(shù),遞歸處理嵌套和類型轉(zhuǎn)換,提升復(fù)用性;
  3. 生產(chǎn)環(huán)境(數(shù)據(jù)驗(yàn)證 + 優(yōu)雅轉(zhuǎn)換) :優(yōu)先使用pydantic.BaseModel,零冗余代碼,自帶驗(yàn)證和自動(dòng)轉(zhuǎn)換,是最優(yōu)雅的方案;
  4. 核心原則:避免手動(dòng)逐個(gè)字段賦值,利用「反射 / 內(nèi)置工具 / 成熟庫」實(shí)現(xiàn)自動(dòng)映射,保證代碼簡(jiǎn)潔且可維護(hù)。

以上就是Python實(shí)現(xiàn)將JSON數(shù)據(jù)轉(zhuǎn)換為數(shù)據(jù)類的方法匯總的詳細(xì)內(nèi)容,更多關(guān)于Python JSON數(shù)據(jù)轉(zhuǎn)數(shù)據(jù)類的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解python程序中的多任務(wù)

    詳解python程序中的多任務(wù)

    這篇文章主要介紹了python程序中多任務(wù)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下
    2020-09-09
  • pandas 選取行和列數(shù)據(jù)的方法詳解

    pandas 選取行和列數(shù)據(jù)的方法詳解

    這篇文章主要介紹了pandas 選取行和列數(shù)據(jù)的方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Python畫圖常用代碼總結(jié)大全(20個(gè)畫圖代碼現(xiàn)拿現(xiàn)用)

    Python畫圖常用代碼總結(jié)大全(20個(gè)畫圖代碼現(xiàn)拿現(xiàn)用)

    Python是一種高級(jí)編程語言,擁有豐富的圖形庫,可以完成繪制各種類型的圖形任務(wù),下面這篇文章主要給大家介紹了關(guān)于Python畫圖常用代碼的相關(guān)資料,文中介紹的這20個(gè)畫圖代碼可以現(xiàn)拿現(xiàn)用,需要的朋友可以參考下
    2023-06-06
  • python中常用檢測(cè)字符串相關(guān)函數(shù)匯總

    python中常用檢測(cè)字符串相關(guān)函數(shù)匯總

    這篇文章主要介紹了python中常用檢測(cè)字符串相關(guān)函數(shù),實(shí)例匯總了Python針對(duì)字符串?dāng)?shù)字、字母、大小寫等常用檢測(cè)函數(shù),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • Python實(shí)現(xiàn)不一樣的猜數(shù)字游戲的示例代碼

    Python實(shí)現(xiàn)不一樣的猜數(shù)字游戲的示例代碼

    大家知道“猜數(shù)字”這個(gè)游戲嗎?顧名思義就是一個(gè)人想一個(gè)數(shù)字,另一個(gè)人猜。本文就來用Python實(shí)現(xiàn)一款不一樣的猜數(shù)字游戲,感興趣的可以了解一下
    2023-02-02
  • Python圖像處理之二值化處理

    Python圖像處理之二值化處理

    所謂”二值化處理“就是將矩陣中每個(gè)點(diǎn)的RGB值(0,0,0)[黑色]或者(255,255,255)[白色],這篇文章主要介紹了Python圖像處理之二值化處理,需要的朋友可以參考下
    2024-05-05
  • Python將數(shù)據(jù)生成二維碼的四種方法實(shí)例代碼

    Python將數(shù)據(jù)生成二維碼的四種方法實(shí)例代碼

    二維碼在日常生活中非常常見,廣泛應(yīng)用于支付、登錄驗(yàn)證、信息分享等場(chǎng)景,下面這篇文章主要給大家介紹了關(guān)于Python將數(shù)據(jù)生成二維碼的四種方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • python關(guān)于倒排列的知識(shí)點(diǎn)總結(jié)

    python關(guān)于倒排列的知識(shí)點(diǎn)總結(jié)

    在本篇文章里小編給大家分享的是一篇關(guān)于python關(guān)于倒排列的知識(shí)點(diǎn)總結(jié),有需要的朋友們可以參考下。
    2020-10-10
  • Pygame Event事件模塊的詳細(xì)示例

    Pygame Event事件模塊的詳細(xì)示例

    事件是Pygame的重要模塊之一,比如鼠標(biāo)點(diǎn)擊、鍵盤敲擊、游戲窗口移動(dòng)、調(diào)整窗口大小、觸發(fā)特定的情節(jié)、退出游戲等等,本文就詳細(xì)的介紹一下具體用法,感興趣的可以了解一下
    2021-11-11
  • 將python包發(fā)布到PyPI和制作whl文件方式

    將python包發(fā)布到PyPI和制作whl文件方式

    今天小編就為大家分享一篇將python包發(fā)布到PyPI和制作whl文件方式,具有很的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12

最新評(píng)論

天水市| 安庆市| 泰来县| 双峰县| 云阳县| 钟山县| 博罗县| 孝感市| 辉南县| 苗栗市| 玛曲县| 长垣县| 通辽市| 定日县| 青州市| 通河县| 额尔古纳市| 乾安县| 米脂县| 会泽县| 牙克石市| 连山| 靖远县| 水城县| 竹山县| 赞皇县| 丰城市| 洛浦县| 七台河市| 陆川县| 鹿泉市| 临安市| 香格里拉县| 鄱阳县| 凤庆县| 明光市| 石首市| 西畴县| 肥乡县| 密山市| 樟树市|