Python
程式架構是什麼?看懂 AI 寫的模組、例外處理與 class
程式架構是什麼?看懂 AI 寫的模組、例外處理與 class
AI 給你的程式只要超過幾十行,一定會拆成模組、例外處理、class 這些基本架構。你不需要自己動手全部寫出來,但看不懂架構,就沒辦法判斷 AI 寫的程式碼安不安全、會不會一遇到錯誤就當機。
這篇文章帶你讀懂 import 怎麼選、try / except 怎麼寫才不會吞掉錯誤、class 的 __init__ 和 self 在做什麼,還有安全讀寫檔案的 with open,最後附上三道可以馬上練習的題目。
你將學到什麼
模組與套件
分清楚 import 的三種寫法,看懂哪些函式庫需要先安裝。
例外處理
用 try / except / finally 讓程式優雅失敗,不再一遇到錯誤就當機。
class 入門
讀懂 __init__ 和 self,看懂 AI 怎麼把邏輯封裝起來。
檔案讀寫
用 with open 安全讀寫檔案和 JSON,不怕忘記關閉檔案。
AI 常見架構陷阱
抓出忘記 encoding、裸露 import *、忘記用 with 這三個常見地雷。
為什麼 Vibe Coder 要懂程式架構?
- 讀懂 AI 給的完整專案:程式只要超過幾十行,AI 幾乎都會拆成函式、class、模組,你要看得懂它怎麼組織。
- 程式不會動不動就當機:例外處理是讓程式優雅失敗的關鍵,沒有 try / except,一個錯誤就會讓整個程式停掉。
- 讓 AI 寫出可以重複使用的程式:知道 class 是什麼,才能告訴 AI 把某段邏輯封裝成一個 class,讓程式更好維護。
- 安全讀寫檔案:
with open()是讀寫檔案的標準寫法,不用它可能讓檔案沒有正確關閉而損毀。
看到 AI 給的程式,問自己三件事:
- 它 import 了什麼?哪些是標準函式庫,哪些需要先
pip install? - 出錯時會怎樣?有沒有 try / except?錯誤訊息看得懂嗎?
- 為什麼要用 class?它在封裝什麼樣的狀態和行為?
模組與套件:import 的正確姿勢
模組(module)是一個 .py 檔案,套件(package)是一個資料夾,裡面放了很多模組。AI 幾乎每一份程式都從 import 開始,你要能一眼分辨它 import 的是哪一種。
# 方式一:import 整個模組(用「模組名.函式」呼叫)
import os
print(os.getcwd()) # 取得目前所在目錄
# 方式二:只 import 需要的部分(可以直接呼叫)
from os.path import join, exists
print(join("data", "file.csv")) # "data/file.csv"
# 方式三:import 並取別名(模組名稱太長時常用)
import datetime as dt
print(dt.date.today())
# 常見標準函式庫速查
import os # 作業系統操作(路徑、目錄)
import sys # Python 執行環境
import json # JSON 讀寫
import re # 正規表達式
import datetime # 日期時間
import pathlib # 路徑操作(現代寫法)
os、json、re)不用安裝,Python 內建就有;第三方套件(requests、pandas、openai)需要先 pip install 套件名。看到 AI 的 import 清單,哪些要先裝好是你必須判斷的事。例外處理:try / except / finally
例外處理讓程式在遇到錯誤時可以優雅失敗,而不是直接當機。任何可能失敗的操作,像是網路、檔案、型別轉換、呼叫 API,都應該包在 try 裡面。
# 基本結構
try:
result = int(input("輸入數字:"))
print(100 / result)
except ValueError:
print("請輸入有效的數字") # 型別轉換失敗
except ZeroDivisionError:
print("不能除以零") # 除以零
except Exception as e:
print(f"未預期的錯誤:{e}") # 捕捉所有其他例外
else:
print("成功!") # try 沒有例外時執行
finally:
print("不管成功或失敗都執行") # 常用來關閉資源
try:
do_something()
except: # 什麼例外都捕捉,連 KeyboardInterrupt 也吞掉!
pass # 靜默忽略,根本不知道出了什麼問題
KeyboardInterrupt 都會被攔下來,出錯時整個程式安靜地什麼事都沒發生,你完全不知道哪裡壞了。看到 AI 寫 except: 或 except Exception: pass,要求它改成指定明確的例外類型,並且加上錯誤記錄,不要靜默吞掉錯誤。except: pass,就是該請 AI 補上防護的時候。class 入門:讀懂 __init__ 與 self
class(類別)是把資料(屬性)和行為(方法)打包在一起的方式。你不需要自己常常寫 class,但 AI 給的程式常常用 class 組織邏輯,你要能讀懂 __init__、self、方法在做什麼。
class Student:
def __init__(self, name, score): # 建構子:建立實例時執行
self.name = name # self.xxx 是實例屬性
self.score = score
def grade(self): # 實例方法,第一個參數固定是 self
if self.score >= 90:
return "優秀"
elif self.score >= 60:
return "及格"
return "不及格"
def __repr__(self): # 決定 print(物件)的顯示方式
return f"Student({self.name}, {self.score})"
# 建立實例
alice = Student("Alice", 92)
print(alice.name) # "Alice"
print(alice.grade()) # "優秀"
print(alice) # Student(Alice, 92)
__init__:建構子,建立物件時自動執行,用來設定初始值self:代表「這個實例本身」,所有方法的第一個參數都是 selfself.屬性:這個物件自己的資料,每個實例各自獨立
檔案讀寫與 with 語法
with open() 是 Python 讀寫檔案的標準寫法,執行完會自動關閉檔案,不需要手動呼叫 .close() 這個動作。AI 寫的所有檔案操作都應該用這個模式。
# 讀取文字檔
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read() # 讀取全部
lines = f.readlines() # 讀取成串列(每行一個元素)
# 寫入文字檔
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Hello\n") # "w" 覆蓋寫入
with open("log.txt", "a", encoding="utf-8") as f:
f.write("新的一行\n") # "a" 附加在結尾
# 讀寫 JSON(最常見)
import json
with open("data.json", "r", encoding="utf-8") as f:
data = json.load(f) # JSON 轉換成 Python 的 dict 或 list
with open("output.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
| 模式 | 說明 | 檔案不存在時 |
|---|---|---|
"r" | 讀取(預設模式) | 會拋出 FileNotFoundError |
"w" | 覆蓋寫入 | 自動建立新檔 |
"a" | 附加在檔案結尾 | 自動建立新檔 |
"x" | 建立新檔,檔名不能重複 | 自動建立;已存在會拋錯 |
AI 常見架構陷阱
陷阱一:忘記指定 encoding,中文會變亂碼
# ❌ 沒有指定 encoding,在 Windows 上中文可能會變亂碼
with open("data.txt", "r") as f:
content = f.read()
# ✅ 永遠指定 encoding="utf-8"
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
encoding="utf-8" 的話,讀寫中文檔案很容易變成亂碼。養成習慣,open() 一律加上 encoding="utf-8"。陷阱二:裸露 import *,污染命名空間
# ❌ from module import * 把所有名稱都引進來
from os import * # os 的所有函式都被引進來,可能蓋掉你自己寫的函式
import * 會把模組裡所有名稱都引進來,可能不小心蓋掉你自己寫的函式,也讓人搞不清楚某個名稱到底從哪裡來。改成具名 import,或是 import 模組名 再用 模組名.函式 呼叫,才看得出來源。陷阱三:不用 with,手動 open 和 close 容易忘記
# ❌ 手動 open / close,例外發生時 close 永遠不會被執行
f = open("data.txt")
data = f.read()
f.close()
# ✅ 用 with open,不管有沒有例外都會自動關閉
with open("data.txt", encoding="utf-8") as f:
data = f.read()
import *;標準函式庫的 import 放最前面,第三方套件放後面;拿到 AI 的程式,把 import 清單複製給它,問清楚哪些需要先 pip install。三道遞進題:讀懂、改寫、抓錯
這三題由淺入深:先讀懂 class 加 try / except 加 with open 混在一起時的執行流程,再練習請 AI 補上完整的例外處理,最後自己抓出 import、encoding、裸露 except 這些最常見的架構地雷。
題目一:讀懂(基礎)
class FileReader:
def __init__(self, path):
self.path = path
def read(self):
try:
with open(self.path, encoding="utf-8") as f:
return f.read()
except FileNotFoundError:
return None
reader = FileReader("notes.txt")
content = reader.read()
print(content)
任務:說明 __init__ 做了什麼、read() 方法的執行流程,以及如果 notes.txt 不存在,print(content) 會輸出什麼。
__init__把傳入的path存成self.path,讓整個 class 都能使用。read()方法用with open安全讀取檔案,並且用 try / except 捕捉FileNotFoundError。- 檔案不存在時,就會拋出
FileNotFoundError,被 except 捕捉後回傳None,所以print(content)顯示的是None。
題目二:改寫(進階)
import json
def load_config(path):
f = open(path)
data = json.load(f)
f.close()
return data["settings"]
請改進
load_config函式,加上:
- 用
with open取代手動 open / closeencoding="utf-8"- try / except 分別處理三種例外:
FileNotFoundError印出找不到檔案的訊息並回傳None;json.JSONDecodeError印出 JSON 格式錯誤並回傳None;KeyError印出缺少 settings 欄位並回傳空的 dict請加上 docstring 和中文註解。
可以直接貼給 AI 的提示詞
- 把
open/close換成with open(path, encoding="utf-8") as f,讓檔案自動關閉,也避免中文亂碼。 - 三個
except分別處理三種不同錯誤,各自印出有意義的訊息,不再靜默失敗。 KeyError回傳{}(空的 dict)而不是None,讓呼叫端能安全地繼續使用 dict 操作。
題目三:抓錯(高階)
架構上的錯誤往往在小專案裡看不出問題,等專案變大才會爆出來。你要在 AI 給程式的當下就看出潛在問題,不要等到上線才發現。
from os import *
from json import *
class DataProcessor:
records = [] # 類別屬性,所有實例共用!
def add(self, item):
self.records.append(item)
def save(self, path):
try:
f = open(path, "w")
f.write(dumps(self.records))
f.close()
except:
pass
任務:找出至少三個問題,說明每個問題的危險原因,並寫出可以請 AI 修正的提示詞。
from os import * 和 from json import * 把所有名稱都引進來,dumps 等函式來源不清楚,也可能被覆蓋。應該改成 import json,再用 json.dumps() 呼叫。records = [] 寫在 class 層級,是類別屬性,所有 DataProcessor 的實例會共用同一份清單。應該搬進 __init__,改成 self.records = []。save() 出錯時完全靜默,使用者不會知道是路徑錯誤、磁碟空間不足,還是其他原因。應該指定明確的例外類型,並且印出錯誤訊息。術語速查表
| 術語 | 說明 |
|---|---|
module(模組) | 一個 .py 檔案;package(套件) 是包含多個模組的資料夾。 |
import X | 引入整個模組,用 X.函式() 呼叫。 |
from X import Y | 只引入模組裡的特定部分,可以直接用 Y() 呼叫。 |
import X as Y | 引入並取別名,常見的例子像 import numpy as np。 |
標準函式庫 vs 第三方套件 | 標準函式庫不需要安裝就能用;第三方套件需要先用 pip install 安裝。 |
try / except | 例外處理的基本結構;except 例外類型 as e 可以取得例外物件本身。 |
finally | 不管 try 成功或失敗都會執行,常用來關閉資源。 |
raise | 主動拋出一個例外,例如 raise ValueError("訊息") 這種寫法。 |
class | 定義一個類別(藍圖),用 類別名() 建立一個實例(物件)。 |
__init__(self) | 建構子,在建立實例時自動被呼叫,用來設定初始屬性。 |
self | 代表實例本身;self.屬性 是屬於這個實例自己的資料。 |
類別屬性 vs 實例屬性 | 類別屬性所有實例共用;實例屬性在 __init__ 裡定義,每個物件各自獨立。 |
with open() as f | 安全讀寫檔案,執行完自動關閉,不用手動呼叫 .close() 就好。 |
encoding="utf-8" | 讀寫中文檔案時一定要指定,否則 Windows 預設的編碼可能會讓中文亂碼。 |
json.load(f) | 從檔案物件讀取 JSON 內容;json.loads(字串) 是從字串讀取。 |
重點整理與自我檢查
| 概念 | 記憶要點 |
|---|---|
| import 選擇 | 具名 import,不用 *;標準函式庫放前面 |
| try / except | 指定明確的例外類型,不要裸露;也不要靜默吞掉錯誤 |
| class 三個關鍵 | __init__、self、實例屬性 vs 類別屬性 |
| 檔案讀寫 | 永遠用 with open,永遠加 encoding="utf-8" |
__init__ 裡還是外面,是共用還是各自獨立?自我檢查清單
- 能分辨標準函式庫和第三方套件,知道哪些需要先
pip install - 能讀懂
try / except / else / finally的執行順序 - 知道裸露的
except: pass有多危險,會主動請 AI 改善 - 能讀懂 class 的
__init__、self、方法怎麼寫 - 知道類別屬性和實例屬性的差別
- 能用
with open(encoding="utf-8")讀寫中文檔案 - 完成題目一:說明 class 加 try 加 with 混合使用時的執行流程
- 完成題目二:請 AI 加上分層的例外處理
- 完成題目三:找出 import *、類別屬性共用、裸露 except 這三個問題
延伸學習
寫給升國一的你的筆記術
寫給剛升上國中的你:筆記不是寫給老師看的,是寫給考前的自己看的。18 章 85 課圖文,從「為什麼要寫」講到七科各自怎麼記,附 78 份可以印出來寫的練習單,以及 80 課家長專區與 34 張三年筆記養成路徑圖。沒有閱讀期限,國一買、國三還在。
NT$ 3,599
HE201|Harness Engineering System Design(6 小時)
六小時的實作課:從 Blueprint 走到可以跑的規格,再用 No-code、n8n 低程式碼與程式碼三條路各做一次同一個 harness,最後處理可靠度——重試、錯誤處理、人工覆核。7 章 54 課,含常見坑與排錯、Capstone 實作,附學員講義 PDF。
NT$ 5,999

