【Python 筆記】JSON 格式讀寫

感謝您點進本篇文章,我是 LukeTseng,該系列主要以筆記加上口語白話形式學習 Python,若文章某處有誤敬請告知,非常感謝。

JSON 是啥?

JSON 全名是 JavaScript Object Notation,這是一種輕量級的資料交換格式,以純文字方式儲存和傳輸資料。雖然名字有 javascript,但他完全獨立於這個程式語言,幾乎所有現代程式語言都支援 JSON 格式。

JSON 的語法很簡單,與 Python 中的字典相似,同樣是採用鍵值對(key-value)的方式組織資料。

JSON 由兩個主要結構組成:

  1. 物件(Object)使用大括號 {} 包起來,含鍵值對。
  2. 陣列(Array)使用中括號 [] 包裹,含有序的值列表。

JSON 的資料型態

JSON 支援六種資料型態,分為簡單型態和複雜型態:

  • 簡單型態:
    • 字串(string):必須用雙引號包裹,如 "name": "LukeTseng"
    • 數字(Number):可為整數或浮點數,如 "age": 25"price": 99.9
    • 布林值(Boolean):只能是 truefalse,不需要引號。
    • 空值(Null):表示空值,使用 null
  • 複雜類型:
    • 物件(Object):無序的鍵值對集合,用大括號 {} 包起來。
    • 陣列(Array):有序的值集合,用中括號 [] 包起來。

JSON 的範例

取自:https://json.org/example.html

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}
}

JSON in Python

Python 本身就有內建 JSON 的套件,使用 import json 這行程式碼即可使用。

這個套件主要就用到以下這四個函式:

  1. json.dumps():將 Python 物件轉換成 JSON 字串。
  2. json.loads():將 JSON 字串轉換成 Python 物件。
  3. json.dump():將 Python 物件寫入 JSON 檔案。
  4. json.load():從 JSON 檔案讀取資料到 Python 物件。

上面四個函式其實是兩個函式,因為你會發現 dump 加一個 s 就是字串的意思。

下表關聯了 JSON 資料型態跟 Python 物件的關係:

PythonJSON
字典(Dict)物件(Object)
列表(List)陣列(Array)
字串(String)字串(String)
數字(Number)數字(Number)
True/Falsetrue/false
Nonenull

1. json.dumps()

語法:

1
2
3
json.dumps(obj, skipkeys=False, ensure_ascii=True,
allow_nan=True, indent=None, separators=None,
sort_keys=False)
  • obj:要轉換的 Python 物件(字典、列表、字串等)。
  • skipkeys:跳過不可序列化的 key,而非引發錯誤。
  • ensure_ascii:如果為 True(預設值),則跳脫(Escape)非 ASCII 字元;設為 False 則保留它們。
  • allow_nan:允許特殊浮點數值(NaN、Infinity)。
  • indent:縮排,可指定為某個數值。
  • separators:更改預設分隔符號。
  • sort_keys:按照字典序對字典鍵進行排序

範例(Python 字典轉 JSON):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import json

# Python Dict
student = {
"name": "LukeTseng",
"age": 18,
"gpa": 4.3,
"courses": ["演算法", "資料結構", "作業系統"],
"level" : "SSR",
}

# 轉換成 JSON 字串
json_string = json.dumps(student)
print(json_string)

Output:

1
{"name": "LukeTseng", "age": 18, "gpa": 4.3, "courses": ["\u6f14\u7b97\u6cd5", "\u8cc7\u6599\u7d50\u69cb", "\u4f5c\u696d\u7cfb\u7d71"], "level": "SSR"}

看來輸出遇到編碼問題了,那這時候只要把 ensure_ascii = False 就好了,因為他預設是開著的,所以會自動把非 ASCII 字元給轉成 Unicode 編碼。

再試一次:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import json

# Python Dict
student = {
"name": "LukeTseng",
"age": 18,
"gpa": 4.3,
"courses": ["演算法", "資料結構", "作業系統"],
"level" : "SSR",
}

# 轉換成 JSON 字串
json_string = json.dumps(student, ensure_ascii=False)
print(json_string)

Output:

1
{"name": "LukeTseng", "age": 18, "gpa": 4.3, "courses": ["演算法", "資料結構", "作業系統"], "level": "SSR"}

你會看到輸出是一行的,這時候可以用 indent 參數調整縮排,讓結果美化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import json

# Python Dict
student = {
"name": "LukeTseng",
"age": 18,
"gpa": 4.3,
"courses": ["演算法", "資料結構", "作業系統"],
"level" : "SSR",
}

# 轉換成 JSON 字串
json_string = json.dumps(student, ensure_ascii=False, indent=4)
print(json_string)

Output:

1
2
3
4
5
6
7
8
9
10
11
{
"name": "LukeTseng",
"age": 18,
"gpa": 4.3,
"courses": [
"演算法",
"資料結構",
"作業系統"
],
"level": "SSR"
}

2. json.loads()

語法:

1
json.loads(s)
  • s:有效的 JSON 字串(可為 str、bytes 或 bytearray 類型)

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import json

# 收到的 JSON 字串
json_data = """
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
"""

# 轉成 Python 字典
menu = json.loads(json_data)
print(menu)
print(menu['menu']['id']) # file
print(type(menu)) # <class 'dict'>

Output:

1
2
3
{'menu': {'id': 'file', 'value': 'File', 'popup': {'menuitem': [{'value': 'New', 'onclick': 'CreateNewDoc()'}, {'value': 'Open', 'onclick': 'OpenDoc()'}, {'value': 'Close', 'onclick': 'CloseDoc()'}]}}}
file
<class 'dict'>

3. json.dump()

語法同 json.dumps()

範例:

1
2
3
4
5
6
7
8
9
10
11
12
import json

# 準備要儲存的資料
students = [
{"name": "LukeTseng", "score": 100},
{"name": "陳圈翔", "score": 87},
{"name": "楊1停", "score": 11}
]

# 寫入檔案
with open('students.json', 'w', encoding='utf-8') as file:
json.dump(students, file, indent=4, ensure_ascii=False)

若目錄沒有檔案的話會自動生成一份檔案,有的話則會覆寫整個檔案。

結果(students.json):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
"name": "LukeTseng",
"score": 100
},
{
"name": "陳圈翔",
"score": 87
},
{
"name": "楊1停",
"score": 11
}
]

4. json.load()

語法同 json.loads()

範例:

沿用上一份範例生成的 students.json

1
2
3
4
5
6
7
8
9
10
import json

# 讀取檔案
with open('students.json', 'r', encoding='utf-8') as file:
students = json.load(file)

print(students)

for student in students:
print(f"{student['name']} 的分數是 {student['score']}")

Output:

1
2
3
4
[{'name': 'LukeTseng', 'score': 100}, {'name': '陳圈翔', 'score': 87}, {'name': '楊1停', 'score': 11}]
LukeTseng 的分數是 100
陳圈翔 的分數是 87
楊1停 的分數是 11

總結

JSON 由兩個主要結構組成:物件(Object)使用大括號 {} 包起來,以及陣列(Array)使用中括號 [] 包起來。

JSON 支援六種資料型態:

簡單型態:

  • 字串(String):必須用雙引號包裹,如 "name": "LukeTseng"
  • 數字(Number):可為整數或浮點數
  • 布林值(Boolean):只能是 truefalse
  • 空值(Null):表示空值,使用 null

複雜型態:

  • 物件(Object):無序的鍵值對集合。
  • 陣列(Array):有序的值集合。

Python 的 JSON 套件

Python 內建的 json 套件提供四個主要函式:

  • json.dumps():將 Python 物件轉換成 JSON 字串(s 代表 string)
  • json.loads():將 JSON 字串轉換成 Python 物件
  • json.dump():將 Python 物件寫入 JSON 檔案
  • json.load():從 JSON 檔案讀取資料到 Python 物件

Python 物件對應 JSON 資料型態關係:

PythonJSON
字典(Dict)物件(Object)
列表(List)陣列(Array)
字串(String)字串(String)
數字(Number)數字(Number)
True/Falsetrue/false
Nonenull

json.dumps() or json.dump() 常用參數:

  • ensure_ascii:預設為 True 會跳脫非 ASCII 字元,設為 False 可保留中文字元
  • indent:設定縮排數值,美化輸出格式
  • sort_keys:按字典序排序鍵
  • skipkeys:跳過不可序列化的鍵

參考資料

json.loads() in Python - GeeksforGeeks

json.dumps() in Python - GeeksforGeeks

Python3 JSON 数据解析 | 菜鸟教程

JSON with Python - GeeksforGeeks

JSON 檔案操作 - Python 教學 | STEAM 教育學習網

JSON Example