跳到主要內容

Web Day 23 前端整合的選擇:HTMX 與 SPA 的取捨

Web Day 23 前端整合的選擇:HTMX 與 SPA 的取捨

執行需求:CPU 可跑。今天開始進入「前端整合」這個區塊。我們在前二十二天把 FastAPI 的核心能力(路由、資料、測試、日誌)都練過一輪,接下來要把 API 接到瀏覽器上。這個區塊的重點不是「教你寫前端」,而是「讓你看到後端怎麼與前端對接」。今天的任務只有一個:盤點選項,看清每條路的成本與適合的場景。

引言

很多後端工程師一聽到「前端整合」就開始焦慮——「我不會 React」「我只寫過 jQuery」「我沒時間學整套前端工具鏈」。但其實,「前端」這件事在 2025 年已經分成兩條明顯分歧的路:一條是「伺服器回傳 HTML,瀏覽器只負責顯示」的傳統模型,由 HTMX 2.0 重新發揚光大;另一條是「伺服器回傳 JSON,瀏覽器用 JavaScript 拼介面」的 SPA(Single Page Application)模型,由 React 19 與 Next.js 15 為代表。兩條路都有成熟生態圈,都能在 2025 年 7 月這個時間點找到豐富的套件與教學。

這篇文章的目的,是幫你回答三個問題:第一,HTMX 跟 SPA 各自的成本與產出是什麼?第二,什麼場景適合選哪一條路?第三,這個系列後續六天(Web Day 24 到 Web Day 29)會走哪一條、為什麼這樣選?我們會先比較兩種架構的核心概念,接著用同一個小範例(待辦清單)分別實作兩個版本,最後整理選型決策樹。貫穿專案「預約管理系統」會在後面的 Web Day 35 開始建構,今天先把工具選好。

兩種架構的核心差異

HTMX 與 SPA 不是「前端框架」對「另一個前端框架」的競爭,它們根本是兩種不同的系統分工方式。先看一張對照表,把心智模型建立起來。

維度 HTMX 2.0(伺服器渲染) SPA(Next.js 15 / React 19)
伺服器回傳 HTML 片段 JSON
前端打包需求 不需要 bundler 需要 bundler(webpack / Turbopack)
互動狀態管理 由伺服器負責 由前端(React state)負責
SEO 友善度 預設友善(HTML 已含內容) 需 SSR / SSG 才能友善
初次載入速度 快,HTML 直接渲染 較慢,需下載整包 JS
互動流暢度 依賴伺服器回應時間 本地操作不需打伺服器
後端模板 Jinja2 / 任何 HTML 模板 JSON + 前端組件
離線運作 不行 可(透過 Service Worker)

HTMX 2.0 在 2024 年底發布穩定版,它的設計哲學是「讓 HTML 變成超媒體」。傳統 HTML 只有 <a> 與 <form> 能發出 HTTP 請求,HTMX 把這個能力擴展到任何元素、任何 HTTP 方法(GET、POST、PUT、DELETE)、任何事件(點選、變更、捲動到某處)。伺服器收到請求後回傳 HTML 片段,HTMX 自動把片段塞回頁面對應位置,開發者不需要寫 JavaScript 也能做出「按按鈕載入新資料」「表單送出後原地更新」的互動。

SPA 模型則把整個畫面包進一個 JavaScript 應用:第一次載入時伺服器回傳一份「空的 HTML + 一大包 JS」,JS 在瀏覽器內跑起來後,用 React 19(或 Vue、Svelte 等)的組件系統拼出畫面,後續所有畫面更新都在本地完成,只有資料存取才需要打伺服器(這時伺服器只回 JSON)。Next.js 15 預設用 React Server Components,把 HTML 渲染責任拉回伺服器,但又允許互動部分保留為 client component,是兩種架構之間的混合方案。

HTMX 的關鍵屬性

為了讓後續 Web Day 24 的實作更有感,今天先把 HTMX 的關鍵屬性(hx-* 開頭)盤一次。這些屬性都掛在普通 HTML 元素上,不需要寫 JavaScript:

屬性 作用 常見搭配
hx-get / hx-post / hx-put / hx-delete 指定觸發的 HTTP 方法與路徑 任何元素
hx-target 回傳片段要塞進哪個 CSS 選擇器 #id、.class
hx-swap 塞入的方式(innerHTML、outerHTML、beforeend 等) outerHTML 適合替換整個元素
hx-trigger 什麼事件觸發(click、change、keyup、revealed) delay 500ms 防抖
hx-include 額外帶哪些表單欄位一起送 搜尋條件與表單混合
hx-confirm 送出前彈出確認對話框 刪除等危險操作

這些屬性背後的設計原則是「駭入 HTML」。原本 HTML 是 markup 語言,只能描述「這是什麼」(標題、段落、表格),HTMX 把「這要怎麼互動」也寫進 HTML。對後端工程師來說,這代表你不需要懂 React 的渲染生命週期、虛擬 DOM、狀態提升,只要會寫 Jinja2 模板就能做出現代化的互動介面。我們會在 Web Day 24 用這些屬性實作一個完整的預約後台預覽,今天先做心理建設。

用一個待辦清單看差異

抽象的比較不容易感受差異,我們用具體範例說明。情境:使用者想新增一筆待辦,看到更新後的清單;可以刪除某一筆;刪除後清單立即更新。先看 HTMX 2.0 的版本(伺服器端 FastAPI):

# main_htmx.py
# HTMX 版本的待辦清單(伺服器回傳 HTML 片段)
import uuid

from fastapi import FastAPI, Form, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory="templates")

# 假資料:實際上線會用 SQLModel 接資料庫(Web Day 6 已示範)
TODOS: list[dict] = []


@app.get("/", response_class=HTMLResponse)
def index(request: Request):
    # 回傳完整 HTML 頁面
    return templates.TemplateResponse(
        request, "index_htmx.html", {"todos": TODOS}
    )


@app.post("/todos", response_class=HTMLResponse)
def create_todo(content: str = Form(...)):
    # HTMX 表單送出後,伺服器只回傳新增的 <li> 片段
    todo = {"id": str(uuid.uuid4()), "content": content}
    TODOS.append(todo)
    # 用 Jinja2 模板渲染單筆條目,HTMX 會自動 append 到清單末尾
    return templates.TemplateResponse("partial_todo.html", {"todo": todo})


@app.delete("/todos/{todo_id}", response_class=HTMLResponse)
def delete_todo(todo_id: str):
    # HTMX 的 DELETE 請求;回傳空字串表示把整個元素從 DOM 移除
    TODOS[:] = [t for t in TODOS if t["id"] != todo_id]
    return ""

搭配兩個 Jinja2 模板。index_htmx.html 是完整頁面(內含一個空清單與表單),partial_todo.html 是單筆的 HTML 片段:

<!-- templates/index_htmx.html -->
<!doctype html>
<html lang="zh-Hant">
<head>
  <meta charset="utf-8">
  <title>HTMX 待辦清單</title>
  <!-- HTMX 2.0:單一檔案、CDN 引入即可 -->
  <script src="https://unpkg.com/htmx.org@2.0.4"
          integrity="sha384-HGfz1gfQXltEFVcsSwPNyBucRoO3ZrAaZEzVcqkcxgYTz32Lpna1eAypVdsT3tbA"
          crossorigin="anonymous"></script>
</head>
<body>
  <h1>待辦清單</h1>
  <ul id="todo-list">
    {% for todo in todos %}
      {% include "partial_todo.html" %}
    {% endfor %}
  </ul>
  <form hx-post="/todos" hx-target="#todo-list" hx-swap="beforeend">
    <input name="content" placeholder="新增待辦" required>
    <button type="submit">新增</button>
  </form>
</body>
</html>
<!-- templates/partial_todo.html -->
<li id="todo-{{ todo.id }}">
  {{ todo.content }}
  <button hx-delete="/todos/{{ todo.id }}"
          hx-target="#todo-{{ todo.id }}"
          hx-swap="outerHTML">刪除</button>
</li>

整份 HTMX 版本只有兩個 HTML 模板與一支 FastAPI 程式,沒有一行 JavaScript。表單送出後,HTMX 把伺服器回傳的 <li> 片段加到清單末尾;刪除按鈕送出 DELETE 請求,伺服器回空字串,HTMX 把對應的 <li> 從 DOM 移除。我們用 curl 驗證一下新增端點(伺服器端)會回什麼:

# 啟動伺服器(在另一個終端機)
uvicorn main_htmx:app --reload --port 8000

# 用 curl 模擬 HTMX 的表單送出
curl -s -X POST http://127.0.0.1:8000/todos \
     -d "content=買牛奶"
# 輸出:<li id="todo-abc123">買牛奶<button hx-delete="/todos/abc123" ...>刪除</button></li>

curl -s -X POST http://127.0.0.1:8000/todos \
     -d "content=回覆信"
# 輸出:<li id="todo-def456">回覆信<button hx-delete="/todos/def456" ...>刪除</button></li>

伺服器回的是純 HTML 片段,HTMX 在瀏覽器收到後會把它塞進 #todo-list 末尾。這驗證了 HTMX 的本質:「瀏覽器是渲染引擎,伺服器是內容來源」,瀏覽器不負責組裝畫面,只負責接收伺服器給的片段並放到對應位置。

對照 Next.js 15(React 19)版本:

// app/page.jsx
// Next.js 15 App Router:client component 處理互動
"use client";

import { useState } from "react";

export default function TodoPage() {
  const [todos, setTodos] = useState([]);
  const [content, setContent] = useState("");

  async function addTodo(e) {
    e.preventDefault();
    // 伺服器只回 JSON,不渲染 HTML
    const res = await fetch("/api/todos", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ content }),
    });
    const todo = await res.json();
    setTodos([...todos, todo]);
    setContent("");
  }

  async function deleteTodo(id) {
    await fetch(`/api/todos/${id}`, { method: "DELETE" });
    setTodos(todos.filter((t) => t.id !== id));
  }

  return (
    <div>
      <h1>待辦清單</h1>
      <ul>
        {todos.map((t) => (
          <li key={t.id}>
            {t.content}
            <button onClick={() => deleteTodo(t.id)}>刪除</button>
          </li>
        ))}
      </ul>
      <form onSubmit={addTodo}>
        <input
          value={content}
          onChange={(e) => setContent(e.target.value)}
          required
        />
        <button type="submit">新增</button>
      </form>
    </div>
  );
}

SPA 版本把「狀態」放進 React 的 useState:新增時送 fetch、更新 todos 陣列、React 重渲染畫面;刪除時送 DELETE、過濾陣列、畫面更新。伺服器端只需要一支簡單的 JSON API:

# api_frontend.py
# 對應 Next.js 前端的 FastAPI JSON API
import uuid

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

app = FastAPI()
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_methods=["*"],
    allow_headers=["*"],
)

TODOS: list[dict] = []


class TodoIn(BaseModel):
    content: str


@app.get("/api/todos")
def list_todos():
    return TODOS


@app.post("/api/todos", status_code=201)
def create_todo(payload: TodoIn):
    todo = {"id": str(uuid.uuid4()), "content": payload.content}
    TODOS.append(todo)
    return todo


@app.delete("/api/todos/{todo_id}", status_code=204)
def delete_todo(todo_id: str):
    TODOS[:] = [t for t in TODOS if t["id"] != todo_id]
    return None

兩種版本功能等價,但成本結構不同。HTMX 版本的後端多寫了兩個 Jinja2 模板、前端完全沒打包步驟;SPA 版本的後端更簡潔(純 JSON)、但前端需要 Node.js 環境、Next.js 工具鏈、React 狀態邏輯、CORS 設定。哪一邊比較划算,要看你的團隊、需求與長期維護成本。

我們也可以用 httpx 程式化測試 JSON API 的行為(這是貫穿後面測試篇章的同一套工具,Web Day 16、17 會詳細展開):

# test_spa_api.py
# 驗證 FastAPI 對 SPA 的 JSON API
import httpx

BASE = "http://127.0.0.1:8000"

with httpx.Client(base_url=BASE, timeout=5.0) as client:
    r = client.post("/api/todos", json={"content": "買牛奶"})
    r.raise_for_status()
    todo = r.json()
    print(todo["id"], todo["content"])
    # 輸出(範例):abc123 買牛奶

    todo_id = todo["id"]
    r = client.delete(f"/api/todos/{todo_id}")
    print(r.status_code)
    # 輸出:204

這個測試跟 Web Day 16 的 TestClient 寫法幾乎相同,只是把測試用的 TestClient(app) 換成真實的 httpx.Client 連到 127.0.0.1:8000。好處是可以對 HTMX 版本與 SPA 版本共用同一套測試基礎設施。

除了「新增 / 刪除」這類一來一回的操作,HTMX 也能做「定時重新整理」與「捲動到位置才載入」。下面示範「輪詢伺服器取得最新待辦」——伺服器提供一個只回部分 HTML 片段的端點,HTMX 每 5 秒自動重抓一次:

# 加上輪詢端點(接續 main_htmx.py)
import time


@app.get("/todos/recent", response_class=HTMLResponse)
def recent_todos(since: float = 0.0):
    # 只回傳時間戳記大於 since 的待辦,避免每次都回整個清單
    fresh = [t for t in TODOS if t["created_at"] > since]
    return templates.TemplateResponse(
        "partial_todos.html", {"todos": fresh}
    )

搭配 hx-trigger="every 5s" 就能讓瀏覽器每 5 秒打一次 /todos/recent:

<!-- 自動更新區塊 -->
<div hx-get="/todos/recent"
     hx-trigger="every 5s"
     hx-swap="afterbegin">
</div>

這個模式在「預約管理系統」會反覆出現:後台想看最新的訂位、通知、未讀訊息時,HTMX 輪詢比寫 WebSocket 簡單。Web Day 28 才會進入 WebSocket 領域,今天先確認這條路存在。我們也用 pytest 為這個端點寫個基本測試,避免改版時把輪詢邏輯改壞:

# test_polling.py
# 驗證 /todos/recent 只回時間戳記大於 since 的條目
from fastapi.testclient import TestClient

from main_htmx import app

client = TestClient(app)

# 先新增一筆待辦
r = client.post("/todos", data={"content": "寫測試"})
assert r.status_code == 200

# 抓取 since=0 的所有待辦
r = client.get("/todos/recent", params={"since": 0.0})
assert r.status_code == 200
assert "寫測試" in r.text

# since 設成未來時間,應該回空
r = client.get("/todos/recent", params={"since": time.time() + 1000})
assert "<li" not in r.text  # 沒有任何 <li> 元素

這個測試展示 pytest + TestClient(Web Day 16 的標準做法)如何驗證 HTMX 端點。測試不需要真的開瀏覽器,只要驗證「伺服器回的字串包含預期的 HTML 片段」即可。

最後順手展示 HTMX 的 loading indicator。當使用者送出請求時,加上一個 spinner 可以避免「我按了沒反應嗎?」的焦慮:

<button hx-post="/todos"
        hx-target="#todo-list"
        hx-swap="beforeend"
        hx-indicator="#spinner">
  新增
</button>
<img id="spinner" class="htmx-indicator" src="/static/spinner.gif">

HTMX 會在送出請求時自動加上 htmx-request class,可以搭配 CSS 控制 spinner 的顯示:

/* 在 static/style.css */
.htmx-indicator {
  display: none;
}

.htmx-request .htmx-indicator {
  display: inline;
}

.htmx-request button[type="submit"] {
  opacity: 0.6;
  pointer-events: none;
}

後端對應的端點只要在處理時間稍長時回傳延遲(例如讀寫資料庫、呼叫外部 API),使用者就會看到 spinner 旋轉。這個模式不需要寫 JavaScript,是 HTMX 最常被低估的功能之一。底下用 httpx 模擬瀏覽器送出表單、驗證伺服器回應的時間戳記格式正確(這是我們常在 production 加的契約測試):

# test_contract.py
# 驗證伺服器回應的 HTML 結構符合 HTMX 預期
import re

import httpx

with httpx.Client(base_url="http://127.0.0.1:8000", timeout=5.0) as client:
    r = client.post("/todos", data={"content": "買牛奶"})
    assert r.status_code == 200
    # 確認回傳的 HTML 含 <li> 與 hx-delete 屬性
    assert re.search(r'<li id="todo-[a-z0-9]+">', r.text)
    assert 'hx-delete="/todos/' in r.text
    print("HTMX 契約測試通過")
    # 輸出:HTMX 契約測試通過

這個契約測試比純單元測試多做一件事:它把 HTMX 的 HTML 結構當成 API 的一部分看待。如果哪天有人把 <button hx-delete> 改成 <form>,這個測試會立刻失敗,提醒團隊「HTMX 的片段是介面契約」。這種測試在多頁應用很有價值,因為它把「瀏覽器對 HTML 的依賴」寫成可自動驗證的規格。

選型決策樹

把「HTMX 還是 SPA」換成幾個可回答的問題,能幫助你快速決策。第一個問題是「頁面內容是否需要即時根據使用者狀態變化?」如果答案是「是」,SPA 通常比較自然——React 的狀態機制(hooks、context、Redux)能優雅處理複雜互動;如果只是「按按鈕載入下一頁片段」,HTMX 就夠了。第二個問題是「SEO 重要嗎?」如果你做的是內部後台、客戶管理系統,SEO 完全不重要;如果是內容網站、電商首頁,HTML 友善度直接影響搜尋排名。第三個問題是「團隊熟悉度」:你的團隊熟 Python 模板還是 JavaScript?強迫不熟 React 的人寫 client component,通常會比強迫不熟 Jinja2 的人寫模板付出更高的學習成本。

本系列後續六天的安排如下:Web Day 24 會用一整篇實作 HTMX 的常見模式(按鈕載入片段、表單送出、刪除元素、輪詢更新);Web Day 25 與 Web Day 26 會用兩篇分別示範 Next.js 15 的「讀取」與「寫入」,只做最小串接、不教完整前端;Web Day 27 處理前端認證的 token 儲存與自動登出;Web Day 28 介紹 WebSocket 即時更新;Web Day 29 進入「上線」前的設定管理。這樣的安排是刻意設計:先把 HTMX 走到能動,再讓 Next.js 走到能讀寫,最後用 WebSocket 補上即時更新的需求。貫穿專案「預約管理系統」會在 Web Day 35 之後用 HTMX 做後台(管理者介面、需要密集互動但 SEO 不重要)、用 Next.js 做對外預約頁(需要 SEO 友善、客戶互動簡單)。

常見錯誤與踩雷

第一個常見的踩雷是「以為 HTMX 不能用於大型應用」。HTMX 2.0 沒有狀態管理、沒有組件系統,但它搭配 Jinja2 模板片段、View Component、甚至是 HTMX 的 OOB(Out of Band)交換,能處理多區塊同時更新的複雜互動。實際上大型內部系統(如 GitHub 的部分後台、一些 CMS)就用 HTMX 做得很順暢。問題不在 HTMX,而在於「單一狀態改變需要同步更新畫面上多個區塊」這種場景,HTMX 需要多個端點配合,比 React 的單一狀態樹麻煩一些。

第二個常見的踩雷是「以為 Next.js 不需要學 React」。雖然 Next.js 15 的 Server Components 能讓你少寫一些 client code,但只要你需要互動(表單、即時更新、動畫),就一定要碰 hooks 與狀態邏輯。把 Next.js 當成「不寫 JS 的後端框架」會撞牆——你終究要懂 React 的渲染生命週期。

第三個常見的踩雷是「混用兩種架構」。例如「主介面用 HTMX,裡面嵌入一個 React 元件做圖表」。這在技術上可行(用 iframe 或 web component 隔離),但會帶來狀態同步、除錯、CSS 隔離等額外成本。除非有強烈的歷史包袱,建議在同一個應用內只選一條路。

第四個是「以為 SPA 比較潮所以比較好」。在內部工具場景,HTMX 的開發速度往往快 SPA 三到五倍。除非使用者明確需要「無刷新切換」「離線運作」「複雜前端狀態」,否則 HTMX 是更務實的選擇。

第五個常見的踩雷是「CORS 沒設好」。如果你用 SPA 模式而忘了設定 CORS(Web Day 15 會展開),瀏覽器會擋住 fetch 請求,只有伺服器看得見 201/204、瀏覽器卻說「No 'Access-Control-Allow-Origin' header is present」。對應排查:先用 curl 確認伺服器本身正常,再用瀏覽器的開發者工具看 network 分頁。

效能與實務提醒

在效能面上,HTMX 的初次載入明顯佔優:瀏覽器拿到完整 HTML 就開始渲染,不需要等 JS 下載完成。但後續互動會多一次 HTTP 往返,使用者每次點按鈕都要等伺服器回應。SPA 初次載入慢(需要下載整包 JS),但後續互動幾乎都在本地完成。對「內容網站」這類以讀取為主的應用,HTMX 的總體體驗通常較好;對「互動工具」這類需要頻繁操作的應用,SPA 的操作流暢度較高。Web Day 28 會介紹 WebSocket,它能讓 HTMX 也達到「部分即時更新」的效果。

實務上的提醒:如果你選 HTMX,後端一定要有完整的測試覆蓋(Web Day 16、17),因為前端能做的事很少,很多錯誤都會直接反映在伺服器回傳的 HTML;如果你選 Next.js,前端的狀態邏輯單測要用 React Testing Library 或 Vitest(Day 16 的延伸),不要只測後端。這系列對 SPA 的測試著墨較少(不是重點),但你自己做專案時務必記得。

最後一個提醒:選 HTMX 不代表放棄前端生態。HTMX 可以與 Alpine.js(輕量 JS 框架,15 KB)搭配,做一些 HTMX 做不到的本地互動(如 modal 切換);也可以單獨使用 Hyperscript(HTMX 團隊出品)寫幾行宣告式腳本。但這些都是加分題,先把 HTMX 純粹用好再考慮。這個系列只走純 HTMX,不混 Alpine / Hyperscript,避免不必要的複雜度。

小結

今天我們把「前端整合」的兩條路線攤開來:HTMX 2.0 走「伺服器回 HTML、瀏覽器只顯示」的路線,後端多寫模板但前端零打包;SPA(Next.js 15 / React 19)走「伺服器回 JSON、前端拼畫面」的路線,前端互動流暢但需要 bundler 與狀態管理。我們用同一個待辦清單範例分別實作兩種版本,凸顯兩者的成本結構。選型沒有標準答案,請依「互動複雜度、SEO 需求、團隊熟悉度」三個維度決定。後續六天的安排是:Web Day 24 實作 HTMX、Web Day 25–26 實作 Next.js 串接、Web Day 27 處理認證、Web Day 28 介紹 WebSocket、Web Day 29 進入上線準備。貫穿專案「預約管理系統」會在 Web Day 35 之後用 HTMX 做後台、用 Next.js 做對外頁。今天先把地圖畫清楚,明天我們就動手寫第一個完整的 HTMX 介面。

結語

今天的重點是「先選路,再上路」。我們比較了 HTMX 2.0 與 SPA(Next.js 15 / React 19)的核心差異、實作了等價範例、給出選型決策樹,並說明本系列後續六天的安排。讀完這篇你應該能回答:HTMX 與 SPA 在後端回傳內容、互動模式、開發成本上有什麼差別?什麼場景適合選哪一條路?為什麼這個系列要先教 HTMX、再教 Next.js?

明天,我們會用一整篇的篇幅把 HTMX 的常見模式走一遍:在 FastAPI 上架設 HTMX 介面、實作「按按鈕載入片段」「表單送出後原地更新」「刪除元素」「輪詢伺服器取得最新資料」四種互動,並且把「待辦清單」延伸成「預約管理系統的後台預覽」。HTMX 的程式碼量會比 Next.js 少很多,但概念需要一次想透;請留一段完整的時間跟著做。

延伸資源

  • HTMX 2.0 官方 Docs(2024):https://htmx.org/docs/,核心概念、hx-* 屬性清單、AJAX 細節。
  • Next.js 15 官方 Docs(2025-07):https://nextjs.org/docs,App Router、Server Components、Client Components 的差異。
  • React 19 官方 Docs(2025):react.dev,hooks、useState、useEffect、Suspense 的現行用法。
  • Jinja2 官方 Docs(2025):https://jinja.palletsprojects.com/,模板語法、巨集、include 與 extends 的搭配。
  • FastAPI 模板支援(0.116,2025):https://fastapi.tiangolo.com/advanced/templates/,Jinja2Templates 的初始化與環境變數注入。

留言

這個網誌中的熱門文章

Day 2 變數與資料型別

Day 2 變數與資料型別 引言 寫程式的過程中,變數與資料型別是處理資料的基礎。變數是存放資料的容器,資料型別則決定這筆資料有哪些特性、可以進行哪些操作。學會定義變數、認識各種資料型別,是學好 Python 的關鍵一步。 這篇文章會帶你了解 Python 中變數的觀念、如何定義變數,以及常見的資料型別,包括整數、浮點數、字串、布林值,還有串列、元組、字典與集合等容器型別。我們也會介紹變數的命名規則與撰寫風格建議,以及如何用 type() 檢查資料型別。 什麼是變數?如何在 Python 中定義變數 變數是在程式執行時用來存放資料的名稱。透過定義變數,我們可以給一筆資料一個名字,並在程式的其他地方用這個名字取用該筆資料。在 Python 中,變數不需要事先宣告型別,因為 Python 是動態型別語言,變數的型別由指定給它的值決定。 定義變數的基本語法 在 Python 中定義變數非常簡單,只要用賦值符號 = 把值指定給變數即可。例如: x = 5 # 定義變數 x,並把整數 5 賦值給它 name = "Alice" # 定義變數 name,並把字串 "Alice" 賦值給它 在這裡,x 是一個變數,被賦予整數 5;name 是另一個變數,被賦予字串 "Alice"。 變數的更新與覆寫 變數的值可以修改,也就是說,我們可以在程式的不同地方給同一個變數新的值。例如: x = 10 # x 最初被賦予 10 x = 15 # x 的值現在被更新為 15 這樣就能依照需求,在程式執行過程中靈活調整變數的值。 Python 的動態型別系統 Python 和某些靜態型別語言不同,定義變數時不需要宣告型別。賦值時,Python 會根據值自動判斷變數的型別。例如: x = 5 # x 是整數 x = 3.14 # x 變成浮點數 x = "Hi" # x 變成字串 同一個變數在程式執行過程中可以存放不同型別的值,這是 Python 的彈性之一。 常見資料型別 在 Python 中,資料型別決定我們可以對變數進行哪些操作...

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門 隨著人工智慧(AI)與深度學習(Deep Learning)快速發展,越來越多人對這些技術產生興趣。不論你是想踏入 AI 領域的初學者,還是已經有程式基礎的開發者,學好 Python 與深度學習框架(例如 PyTorch),都能為你打開更多可能。 為什麼選擇 Python? Python 已經是資料科學與人工智慧領域的首選語言。它的語法簡潔、容易上手,而且擁有龐大的生態系與大量開源函式庫。無論是資料處理、資料視覺化,還是建立機器學習與深度學習模型,Python 都能勝任。對想進入 AI 或資料科學領域的人來說,它幾乎是必備工具。 PyTorch 是什麼? PyTorch 是由 Meta(原 Facebook)AI 研究團隊開發的開源深度學習框架,以易用、靈活和動態計算圖著稱,是許多 AI 研究人員與開發者的首選。相較於其他框架,PyTorch 的寫法更貼近原生 Python,對初學者相對友善。無論是簡單的實驗,還是複雜的深度學習模型,PyTorch 都能提供強大的支援。 這個系列能帶給你什麼? 這個系列會從 Python 的基礎開始,帶你一步一步學習,最後能自己用 PyTorch 建立深度學習模型。即使你完全沒有寫過程式,也能跟著文章的節奏累積技能,理解 AI 與深度學習的核心觀念。 本系列涵蓋的主題 Python 基礎:從變數、條件判斷到函式與模組。 資料處理工具:用 NumPy 與 Pandas 有效率地操作資料。 資料視覺化:用 Matplotlib 與 Seaborn 把資料畫成圖表。 深度學習的數學基礎:線性代數、微積分與機率。 PyTorch 入門:理解張量、模型建構與 GPU 加速。 基礎深度學習模型:CNN 與 RNN 的實作應用。 深度學習專案實戰:從資料前處理到模型部署的端到端流程。 誰適合這個系列? 程式初學者 :如果你對 AI 充滿好奇,卻還沒寫過程式,系列的第一部分會帶你快速上手 Python,並幫助你理解深度學習的基本觀念。 資料科學愛好者 :如果你已經熟悉一些資料處理方法,進階部分會教你如何用 PyTorch 建構深度學習模型。 開發者與研究人員 :想更深入了...

Day 1 Python 簡介與環境設定

Day 1 Python 簡介與環境設定 引言 在現在的科技環境裡,程式設計已經是一項重要技能。無論你是對資料科學有興趣、想成為開發者,或是想踏入人工智慧(AI)領域,學會寫程式都能明顯提升你的競爭力。在眾多程式語言中,Python 因為語法簡單、功能強大、應用範圍廣泛,成為許多人進入程式世界的第一選擇。這篇文章會帶你認識 Python 的背景與優勢,並一步步教你在不同系統上安裝與設定 Python 開發環境,最後寫出第一支 Python 程式。 為什麼選擇 Python? Python 是一種高階程式語言,由 Guido van Rossum 在 1991 年發布。Python 的設計哲學強調程式碼的可讀性,並用縮排來定義程式區塊,這點和許多使用大括號的語言不同。簡潔的語法讓它成為初學者的理想選擇;就算是經驗豐富的開發者,也能用它完成複雜的專案。 Python 的優勢如下: 簡單易學 :Python 的語法清楚、結構簡潔,初學者很快就能上手。和其他語言相比,學習曲線相對平緩,不需要先弄懂一堆複雜觀念,就能開始寫程式。 應用範圍廣泛 :從資料科學、網頁開發、人工智慧、機器學習、自動化測試到網路爬蟲,Python 都有大量開源函式庫與工具支援,而且在這些領域都扮演關鍵角色。 豐富的函式庫與框架 :Python 的函式庫生態系非常龐大。做資料分析有 NumPy、Pandas;開發網站有 Django、Flask;做深度學習有 TensorFlow、PyTorch。各種需求幾乎都能找到對應的套件,讓開發更有效率。 跨平台支援 :Python 支援 Windows、macOS、Linux 等作業系統,程式通常不需要太多修改就能跨平台執行,讓開發與部署更有彈性。 活躍的社群 :Python 擁有龐大的開發者社群。學習或開發上遇到問題,幾乎都能在社群與論壇(例如 Stack Overflow)找到答案,對初學者來說是很強的後盾,也能減少卡關時的挫折感。 Python 的應用領域 Python 的流行與強大功能,讓許多領域都開始大量使用它。以下是幾個常見的應用方向: 資料科學 :隨著大數據與人工智慧興起,資料科學大量使用 Python。NumPy、Pandas 與 Matplotlib 等工具能處理和分析龐...