JSON
一種把資料寫成文字的格式,用大括號、方括號和雙引號標出結構。語法嚴格,適合程式之間交換資料。
- 出處
- M0 資料的一生 · 同一份資料,兩種寫法 →
- 參考
- json.org ↗
- 相關
- YAML、字典
一種把資料寫成文字的格式,用大括號、方括號和雙引號標出結構。語法嚴格,適合程式之間交換資料。
一種把資料寫成文字的格式,用縮排和「- 」標出結構,可以寫註解。寫法寬鬆,常用於設定檔。
Python 的內建容器,存放一組「鍵:值」。JSON 的物件和 YAML 的映射讀入 Python 後都會變成 dict。
副檔名為 .ipynb 的檔案,把程式、執行結果和說明文字按 cell 存在一起。
notebook 裏的一格。程式 cell 可以單獨執行,結果顯示在它下面;Markdown cell 用來寫說明。
在瀏覽器裏編輯和執行 notebook 的工作環境。它只是執行 Python 的其中一個地方。
執行 Python 程式的程式,即是輸入 python 時啟動的那一個。同一部電腦上可以有好幾個,sys.executable 會告訴你現在用的是哪一個。
別人寫好、可以安裝來用的程式碼,例如讀寫 YAML 的 PyYAML。安裝時的名稱和 import 時的名稱不一定相同。
一個專案專用的資料夾(本課是 .venv),裏面有一個直譯器和這個專案的套件。可以隨時刪除,再按鎖定檔重建。
本課用來管理 Python 的工具:下載合適版本的直譯器、建立虛擬環境、安裝套件。在專案裏用 uv run 執行命令,保證用的是專案自己的環境。
專案的說明檔,寫明需要哪個版本的 Python、直接用到哪些套件。給人讀和改,要交給別人。
記錄每一個套件(包括間接用到的)準確版本的檔案,本課是 uv.lock。由 uv 生成,不要手改;別人憑它可以重建出一模一樣的環境。
notebook 背後執行程式的 Python。變數只存在它的記憶體裏;儲存 notebook 不會保存變數,重新啟動會清空記憶體。
code cell 左邊的 [n],表示這一格是 kernel 第幾次執行的。跳號或不由上而下遞增,代表 notebook 曾經亂序執行。
清空 kernel 的記憶體,再由第一格順序執行全部 cell。執行後編號由 [1] 起逐一遞增、沒有錯誤,結果才可信。
一個值屬於哪一類,決定了它能做甚麼運算。用 type() 查出,例如 int、float、str、bool、NoneType。
文字,用引號包住。看起來像數字的字串(例如 "120")仍然是文字,要先用 int() 或 float() 轉換才能計算。
有小數點的數字。電腦只能儲存大部分小數的近似值,所以不要用 == 比較兩個 float。
只有 True 和 False 兩個值,比較的結果就是布林值。bool("False") 是 True,因為 bool() 只看有沒有內容。
Python 表示「沒有值」的方法,對應 JSON 的 null。它和 0、空字串都不同;檢查時用 is None。
貼在值上的名字。把名字改貼到另一個值上,原來的值和貼在它上面的其他名字都不受影響。
把很多個值放在一起的值。最常用的是 list、dict、tuple、set;JSON 和 YAML 讀入後只會出現 list 和 dict。
有次序、可以修改的一串值,用方括號寫。JSON 的陣列讀入 Python 後就是 list。索引由 0 開始。
一項在 list 或 tuple 裏的位置,由 0 開始數;負數由尾數起,-1 是最後一項。超出範圍會報 IndexError。
dict 裏用來找值的名字。用不存在的鍵會報 KeyError;不確定有沒有時,用 get() 並給預設值。
有次序、建立後不能修改的一組值,用圓括號寫,適合座標這類固定在一起的值。JSON 沒有 tuple,寫出時變成陣列。
沒有次序、不重複的一組值,適合「有沒有」和去除重複。JSON 沒有 set,寫出前要先轉成 list。
對一個容器裏的每一項重複執行同一段程式。for item in items:每一輪把下一項交給 item 這個名字。
結果是 True 或 False 的運算式,寫在 if、elif 後面,決定那一段程式執行不執行。可以用 and、or、not 組合。
行首的空白。Python 用縮排判斷哪些程式屬於 if 或 for(本課一律四個空格);縮排不一致會報 IndentationError。
用一行寫出「走過一個容器、按條件篩選、產生新容器」,例如 [b["title"] for b in books if b["stock"] == 0]。讀時先讀 for,再讀 if,最後讀最前面的值。
起了名字的一段程式。用 def 定義,加括號呼叫;需要的資料從參數進來,結果用 return 交出去。
定義函式時括號裏的名字,例如 def order_total(order, titles) 裏的 order 和 titles。可以有預設值。
呼叫函式時放進去的實際值。按位置對應參數,或者用關鍵字寫明交給哪個參數(discount=0.9)。
函式用 return 交回給呼叫處的值。沒有寫 return 的函式回傳 None;print 只顯示給人看,不是回傳值。
一個 .py 檔,裏面的函式可以用 import 取用。標準函式庫、第三方套件和自己寫的 .py 檔都是模組。
隨 Python 附送、不用安裝的模組,例如 json、pathlib、math、statistics。
檔案的地址。絕對路徑由磁碟頂層寫起;相對路徑由工作目錄起計,資料夾搬走後仍然有效。本課用 pathlib 的 Path 處理。
程式找相對路徑時的起點,用 Path.cwd() 查出。notebook 的工作目錄是它所在的資料夾;.py 腳本的是終端機當時所在的資料夾。
把文字變成位元組的規則。新檔案多用 UTF-8,舊的繁體中文系統常用 Big5。讀寫文字檔時一律寫明 encoding="utf-8"。
json.loads 讀到不合法的 JSON 時報的錯,訊息最後有行號和欄號。錯誤常常在報告的位置之前,先看那一行,再看上一行的行尾。
每一行是一個獨立 JSON 的檔案格式(副檔名 .jsonl),常用於記錄檔。可以一直在尾加新行,也可以逐行讀;整個檔交給 json.loads 會報 Extra data。
YAML 裏一組「鍵:值」,對應 JSON 的物件,讀入 Python 是 dict。同一個映射裏重複的鍵,PyYAML 不報錯,只保留最後一個。
YAML 按值的樣子猜它的型別。PyYAML 跟 YAML 1.1,會把 NO 讀成 False、010 讀成 8、9:30 讀成 570。不是用來計算的值,就加引號。
PyYAML 只建立普通值(dict、list、字串、數字)的讀入函式。yaml.load 在某些設定下會按檔案指示建立任何物件,所以一律用 safe_load。
以逗號分隔欄位、一行一筆記錄的表格格式,Excel 可以直接開。讀入的值一律是字串;Excel 存的 CSV 開頭有 BOM,要用 encoding="utf-8-sig" 讀。
給人寫、給工具讀的設定檔格式,例如 pyproject.toml。字串一定要加引號,所以不會像 YAML 那樣猜型別。Python 內建的 tomllib 只能讀,不能寫。
用 JSON 描述「一份資料應該長甚麼樣」的標準寫法(型別、必要的鍵、範圍)。用 jsonschema 套件驗證;它只檢查,不轉換。
pandas 的表格:一行一筆、一欄一個欄位。由 list of dict 直接建立;對一欄做運算會對每一行做,不用寫迴圈。取出一欄得到 Series。
pandas 表格裏的一欄(或一行),df["price"] 取出的就是 Series。
按一欄把行分組,對另一欄計算,例如 items.groupby("month")["amount"].sum()。數「有幾個不同的值」用 nunique。
准許註解的 JSON(JSON with Comments),VS Code 的 settings.json 用的就是它。json.loads 讀不了,要先去掉註解。
Markdown 檔開頭用 --- 包住的一段 YAML,放標題、日期、標籤等資料。本課每個單元頁、Obsidian 和很多網站產生器都這樣用。
.github/workflows/ 裏的 YAML 檔,告訴 GitHub 在甚麼時候(on)執行甚麼工作(jobs、steps)。版本號要加引號,否則 3.10 會變成 3.1。
本課指專門給程式讀的網址:用參數說明要甚麼,回來的是 JSON 而不是網頁。天文台的開放資料 API 不用登記;參數錯了,回來的可能不是 JSON。
公開給任何人使用的資料,例如經 DATA.GOV.HK 提供的天文台資料。可以免費使用和轉載,但要遵守使用條款,通常必須註明資料來源。
找不到相符的術語。