← 返回大綱
第四章

函式定義
與參數傳遞

Functions & Arguments

用撲克牌遊戲來學 def!

概念

函式是什麼?

函式就像一台飲料販賣機

投入硬幣

= 傳入參數
deal("小明")

機器運作

= 函式本體
裡面的程式碼

掉出飲料

= 回傳值
return card

簡單來說

函式 = 把一段程式碼取名字包起來,需要時叫名字就能重複使用。
就像食譜一樣 — 寫一次,做多次!

為什麼需要函式?

重複的程式碼 → 包成函式

想像你在寫撲克牌遊戲,每次發牌都要寫一堆一樣的程式碼...

# 不用函式 → 每次發牌都要重複寫
import random
deck = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
card1 = random.choice(deck)
print(f"你抽到:{card1}")

# 又要發一張...又要複製貼上一次?
card2 = random.choice(deck)
print(f"你抽到:{card2}")

# 如果發牌規則要改,每個地方都要改... 😱
解法

把「發牌」這件事包成函式,以後只要呼叫一行就好!

Scratch → Python

自製積木 → def

Scratch
定義 發牌
說出 "你抽到一張牌!"

發牌
Python
def deal():
    print("你抽到一張牌!")

deal()   # 呼叫函式
函式的結構

def 名稱(): 定義函式,縮排的內容是函式本體。
呼叫時打 名稱(),括號不能省!

語法

def 語法拆解

#  關鍵字   函式名稱   參數列     冒號
#   ↓        ↓        ↓         ↓
    def    deal    ( player ):
        print(f"{player} 抽到一張牌!")   # ← 函式本體(要縮排)
#       ↑
#     這裡面的程式碼,呼叫時才會執行

# 呼叫函式:
deal("小明")     # 括號裡放「引數」,傳給參數 player
術語說明範例
def定義函式的關鍵字def deal():
參數 parameter函式接收的變數(定義時)player
引數 argument呼叫時傳入的值"小明"
return回傳結果給呼叫者return card
函式

參數 (Parameters)

函式可以接收「參數」,讓它更有彈性:

Scratch
定義 發牌 player
說出 player + " 抽到一張牌"
Python
def deal(player):
    print(f"{player} 抽到一張牌!")
deal("小明")    # 小明 抽到一張牌!
deal("小華")    # 小華 抽到一張牌!

# 多個參數
def show_card(player, card):
    print(f"{player} 的牌是 {card}")

show_card("小明", "A♠")   # 小明 的牌是 A♠
概念

print vs return 差在哪?

print = 大聲說出來

像發牌員喊出「這張是 A!」
你聽到了,但手上沒拿到牌。
程式無法繼續使用這個值。

def draw():
    print("A")  # 喊出來

result = draw()
# result 是 None 😢

return = 把牌遞給你

像發牌員把牌交到你手上。
你拿到了,可以繼續用。
程式可以存起來使用

def draw():
    return "A"  # 交給你

result = draw()
# result 是 "A" 🎉
函式

回傳值 return

print() 是給人看的,return 是把值傳回給程式用:

import random

ranks = ["A", "2", "3", "4", "5", "6", "7",
         "8", "9", "10", "J", "Q", "K"]

def draw_card():
    card = random.choice(ranks)
    return card          # 把牌回傳出去

# 回傳的值可以存進變數
my_card = draw_card()
print(f"你抽到:{my_card}")

# 也可以直接用
print(f"電腦抽到:{draw_card()}")
沒有 return 會怎樣?

沒寫 return 的函式會回傳 None,存進變數就是空的。

函式

預設參數值

參數可以設預設值,呼叫時不傳就用預設:

import random
ranks = ["A", "2", "3", "4", "5", "6", "7",
         "8", "9", "10", "J", "Q", "K"]

def deal(n=1):
    """發 n 張牌,預設發 1 張"""
    hand = []
    for i in range(n):
        hand.append(random.choice(ranks))
    return hand

print(deal())      # ['7']         ← 預設 1 張
print(deal(3))     # ['A', '5', 'K']  ← 指定 3 張
print(deal(5))     # ['2', '9', 'J', '6', '3']
關鍵字引數

也可以用名稱指定:deal(n=5),順序就不重要了。

函式

回傳多個值

Python 函式可以一次回傳多個值(用逗號隔開):

def card_value(card):
    """回傳牌面和點數"""
    values = {"A": 14, "K": 13, "Q": 12, "J": 11}
    if card in values:
        point = values[card]
    else:
        point = int(card)
    return card, point     # 回傳兩個值

name, pts = card_value("A")
print(f"{name} 值 {pts} 點")   # A 值 14 點

name, pts = card_value("7")
print(f"{name} 值 {pts} 點")   # 7 值 7 點
函式

函式的作用域 (Scope)

比喻

全域變數 = 公布欄上的資訊,大家都看得到。
區域變數 = 函式房間裡的東西,出了房門就看不到了。

player = "小明"    # 全域變數

def play_round():
    card = "A♠"    # 區域變數(只在函式內有效)
    print(f"{player} 出了 {card}")  # ✅ 可以讀全域

play_round()       # 小明 出了 A♠
print(player)      # ✅ 小明
# print(card)      # ❌ 錯誤!card 在函式外不存在

全域變數

  • 在函式外面定義
  • 任何地方都能讀

區域變數

  • 在函式裡面定義
  • 只在函式內有效
函式

函式可以呼叫其他函式

把大問題拆成小函式,再組合起來:

import random

ranks = ["A", "2", "3", "4", "5", "6", "7",
         "8", "9", "10", "J", "Q", "K"]
values = {"A":14,"K":13,"Q":12,"J":11,
          "2":2,"3":3,"4":4,"5":5,"6":6,
          "7":7,"8":8,"9":9,"10":10}

def draw():
    return random.choice(ranks)

def get_value(card):
    return values[card]

def compare(card1, card2):
    """比較兩張牌,回傳贏家"""
    if get_value(card1) > get_value(card2):
        return "玩家"
    elif get_value(card1) < get_value(card2):
        return "電腦"
    else:
        return "平手"
實作練習

動手做:翻牌比大小

import random

ranks = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
values = {"A":14,"K":13,"Q":12,"J":11,
          "2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,"10":10}

def draw():
    return random.choice(ranks)

def get_value(card):
    return values[card]

# --- 遊戲開始 ---
print("🃏 翻牌比大小!\n")
input("按 Enter 翻牌...")

p_card = draw()
c_card = draw()
print(f"你:{p_card}({get_value(p_card)} 點)")
print(f"電腦:{c_card}({get_value(c_card)} 點)\n")

if get_value(p_card) > get_value(c_card):
    print("🎉 你贏了!")
elif get_value(p_card) < get_value(c_card):
    print("😢 電腦贏了!")
else:
    print("🤝 平手!")

第四章完成!

學會了 def、參數、return、預設值與作用域。
下一章用 list 建出完整的牌組!