目錄

引言

一、JSON簡介

二、python中JSON模塊

2.1 json.load()

2.2 json.loads()

2.3 json.load()

2.4 json.dumps()

三、數據格式轉換規則

四、異常處理

五、完整示例

參考


引言

        在當今數據驅動的世界中,JSON已成為數據交換的事實標準。無論是與 Web API 交互、配置應用程序、存儲結構化數據,還是處理來自物聯網設備的數據,幾乎不可避免地會遇到 JSON 格式。

一、JSON簡介

        JSON(JavaScript Object Notation)是一種輕量級的、基於文本的數據交換格式。它被設計為易於人閲讀和編寫,同時也易於機器解析和生成,被廣泛應用於各種編程語言和平台之間。

JSON 數據由鍵值對組成,支持以下幾種基本數據類型

  • 對象 (Object): 用花括號 {} 包圍,包含零個或多個鍵值對,鍵是字符串,值可以是任何有效的 JSON 數據類型。
  • 數組 (Array): 用方括號 [] 包圍,包含零個或多個值,值之間用逗號分隔。
  • 字符串 (String): 用雙引號 "" 包圍的字符序列。
  • 數字 (Number): 整數或浮點數。
  • 布爾值 (Boolean): true 或 false
  • 空值 (Null): null

例如:

people.json文件:

[
  {
    "name": "張三",
    "gender": "男",
    "age": 25
  },
  {
    "name": "李四",
    "gender": "女",
    "age": 23
  }
]

二、python中JSON模塊

Python 的 JSON模塊是處理 JSON 數據的標準工具。它提供了四個核心函數用於在 JSON 字符串/文件和 Python 對象之間進行轉換:

2.1 json.load()

從 JSON文件對象讀取並解析為Python 對象。

json.load(fp, *, cls=None, object_hook=None, parse_float=None, 
            parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
  • 參數:
  • fp: 一個支持 .read() 方法的文本文件對象,數據從這個文件對象中讀取。
  • cls
  • object_hook
  • parse_float (可選): 一個函數,用於將 JSON 中的浮點數字符串轉換為 Python 對象。默認是 float
  • parse_int
  • parse_constant (可選): 一個函數,用於處理 JSON 常量 ('-Infinity''Infinity''NaN')。
  • object_pairs_hook (可選): 一個函數,接收一個由 (key, value) 對組成的列表,並返回一個對象。object_pairs_hook 優先於 object_hook
  • **kw
  • 返回值: 一個 Python 對象(通常是 dict 或 list)。

2.2 json.loads()

 從JSON 字符串(str)讀取並解析為 Python 對象。

json.loads(s, *, cls=None, object_hook=None, parse_float=None, 
           parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

參數同json.dump。

2.3 json.load()

將 Python 對象 編碼為 JSON格式寫入文件。

json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, 
            check_circular=True, allow_nan=True, cls=None, indent=None, 
            separators=None, default=None, sort_keys=False, **kw)
  • 參數:
  • obj: 一個必需的參數。要序列化的 Python 對象。它必須是 dictlisttuplestrintfloatboolNone,或者是一個實現了 __json__() 方法的對象。
  • fp: 一個必需的參數。一個支持 .write() 方法的文本文件對象(通常由 open() 函數返回,模式為 'w' 或 'a')。JSON 數據將寫入這個文件對象。
  • skipkeys (可選): 如果為 True,當字典的鍵不是基本類型(strintfloatboolNone)時,會自動跳過該鍵值對,而不是引發 TypeError
  • ensure_ascii (可選): 如果為 True,輸出將確保所有非 ASCII 字符都被轉義。如果為 False,則允許直接輸出這些字符(通常用於生成人類可讀的文件)。
  • check_circular (可選): 如果為 True,會檢查容器類型的循環引用(如列表包含自身),如果發現則引發 ValueError。如果為 False,則不檢查,但遇到循環引用時行為未定義。
  • allow_nan (可選): 如果為 True,允許 float 類型的 NaNInfinity-Infinity。如果為 False,則在序列化這些值時會引發 ValueError
  • cls (可選): 用於自定義 JSON 編碼器的類。
  • indent (可選): 用於美化輸出。如果是一個非負整數或字符串(如 '\t'),則 JSON 數組元素和對象成員將被換行並使用該值進行縮進,使其更易讀。None(默認)表示單行輸出。
  • separators (可選): 一個 (item_separator, key_separator) 元組。默認是 (', ', ': ')。可以設置為 (',', ':') 以減少輸出大小(去除空格)。
  • default (可選): 一個函數,用於處理 json 模塊無法序列化的對象。該函數應返回一個可序列化的對象,或者引發 TypeError
  • sort_keys (可選): 如果為 True,則字典的輸出將按鍵的字符串表示進行排序。
  • **kw (可選): 其他關鍵字參數。
  • 返回值: 無 (None)。

2.4 json.dumps()

將 Python 對象 編碼為 JSON 字符串(str)。

json.dumps(obj, *, skipkeys=False, ensure_ascii=True, 
           check_circular=True, allow_nan=True, cls=None, indent=None, 
           separators=None, default=None, sort_keys=False, **kw)

參數同json.dump。

三、數據格式轉換規則

Python 對象與 JSON 值之間的轉換規則是數據處理的關鍵。

Python-JSON 數據類型映射表

JSON

Python

object

dict

array

list

string

str

number (int)

int

number (real)

float

true

True

false

False

null

None

注意:

  • JSON 的 null 對應 Python 的 None
  • JSON 的 true/false 對應 Python 的 True/False

四、異常處理

JSONDecodeError ValueError 的一個子類,提供了更豐富的錯誤信息,當解析 JSON 文檔時發生錯誤(即 JSON 格式不正確)時會引發此異常,這對於調試 JSON 格式問題非常有幫助。

(該異常在 Python 3.5 版本中添加)

exception json.JSONDecodeError(msg, doc, pos)

額外的屬性:

  • msg: 未格式化的錯誤消息(即描述錯誤原因的文本)。
  • doc: 正在被解析的原始 JSON 文檔(字符串)。
  • pos: 在 doc 字符串中,解析失敗開始的索引位置(從 0 開始的字符位置)。
  • lineno: 與 pos 位置對應的行號(從 1 開始計數)。
  • colno: 與 pos 位置對應的列號(從 1 開始計數)。



示例:

新建一個bad.json文件:

{
  "name": "Alice",
  "age": 30,  // 這裏多了一個逗號
}

嘗試解析它:

import json

try:
    with open('bad.json', 'r') as file:
        data = json.load(file)
except json.JSONDecodeError as e:
    print(f"錯誤消息: {e.msg}")
    print(f"錯誤位置: 第 {e.lineno} 行, 第 {e.colno} 列")
    print(f"錯誤索引: {e.pos}")
    # 如果需要,可以打印整個文檔或相關部分
    # print(f"文檔: {e.doc}")

可能的輸出:

錯誤消息: Expecting property name enclosed in double quotes
錯誤位置: 第 3 行, 第 2 列
錯誤索引: 35

五、完整示例

解析第一章節中的people.json文件:

import json

# 1. 定義文件名
filename = 'people.json'
try:
    # 2. 打開文件並讀取
    with open(filename, 'r', encoding='utf-8') as file:
        # 3. 使用 json.load() 解析文件內容
        data = json.load(file)
    
    # 4. 打印解析結果,驗證數據類型和內容
    print("=== 解析結果 ===")
    print("原始數據類型:", type(data)) # <class 'list'>
    print("解析後的數據 (Python 列表):")
    print(data)
    print("\n") 

    # 5. 訪問和使用數據
    print("=== 信息 ===")
    for person in data:
        print(f"{person['name']} - {person['gender']}, {person['age']}歲")

except FileNotFoundError:
    print(f"錯誤:找不到文件 '{filename}'。")
    print("請確保 'people.json' 文件存在於當前目錄,或者檢查文件名是否正確。")
except Exception as e:
    print(f"發生未知錯誤: {e}")

結果:

=== 解析結果 ===
原始數據類型: <class 'list'>
解析後的數據 (Python 列表):
[{'name': '張三', 'gender': '男', 'age': 25}, {'name': '李四', 'gender': '女', 'age': 23}]

=== 信息 ===
張三 - 男, 25歲
李四 - 女, 23歲

參考

  • python官方文檔