CodeSprout程式萌芽

CHAPTER 06 · PYTHON FOUNDATIONS

Function (函式)

把一件事整理成可以呼叫的功能,清楚設計輸入、處理與回傳值。

這一章學會
  • 用 def 定義函式與參數
  • 分辨 return、print 與區域變數
  • 拆解小步驟並以多組輸入驗證
先預測結果,再看輸出。

這裡的範例是可在 Python 3 執行的獨立小程式;輸出框是預先核對的結果。題庫作答時,請保留題目提供的 solve 與參數,使用 return 交回答案。模組章的雙檔範例會另外標明操作方式。

01|定義不等於執行

def 後面是函式名稱與參數,冒號後的縮排是函式內容。定義完成只是準備好功能,呼叫名稱並加上括號才會執行。參數是函式內使用的名字,呼叫時傳入的是實際資料。

PYTHON程式碼
def greet(name):
    return f"你好,{name}!"

print(greet("小芽"))
print(greet("小林"))
預期輸出
你好,小芽!
你好,小林!

02|return 把資料交給呼叫者

return 交回結果並結束這次呼叫;呼叫者可以保存、印出或繼續計算。print 只負責顯示。如果函式沒有走到任何 return,結果就是 None。

PYTHON程式碼
def double(number):
    return number * 2

def show_double(number):
    print(number * 2)

result = double(6)
print(result + 1)
print(show_double(6))
預期輸出
13
12
None

03|參數順序、關鍵字與預設值

位置參數按順序傳入;關鍵字參數用名稱指明用途。預設值讓呼叫者可以省略某個資料。一般必填參數放前面,有預設值的參數放後面;不要把同一個參數同時用位置和關鍵字提供兩次。

PYTHON程式碼
def total_price(price, quantity=1):
    return price * quantity

print(total_price(20))
print(total_price(20, 3))
print(total_price(quantity=4, price=15))
預期輸出
20
60
60

04|函式裡的變數有自己的範圍

函式內指定的名字通常是區域變數,每次呼叫各自計算。不要讓函式偷偷依賴外部資料;把需要的資料當參數傳入,結果用 return 交回,會比較容易理解與測試。

PYTHON程式碼
amount = 100

def add_fee(amount):
    amount = amount + 5
    return amount

print(add_fee(20))
print(amount)
預期輸出
25
100

05|把大步驟拆成小函式

每個函式盡量只處理一件能清楚描述的事。下例先定義判斷是否達標,再用另一個函式統計。小函式能單獨測試,出錯時比較容易找到是哪個步驟。

PYTHON程式碼
def is_passed(score):
    return score >= 60

def count_passed(scores):
    count = 0
    for score in scores:
        if is_passed(score):
            count += 1
    return count

print(is_passed(60))
print(count_passed([59, 60, 85]))
print(count_passed([]))
預期輸出
True
2
0

06|用 None 避免共用預設清單

預設參數的物件會在定義函式時建立。若用 [] 當預設值又在函式內 append,不同呼叫可能共用同一份清單。需要每次獨立的新清單時,先用 None 當預設,再在函式裡建立。

PYTHON程式碼
def add_note(text, notes=None):
    if notes is None:
        notes = []
    notes.append(text)
    return notes

print(add_note("讀題"))
print(add_note("測試"))
預期輸出
['讀題']
['測試']

07|作答時保留 solve,讓測資呼叫它

本站每組測資會呼叫一次 solve。可以在同一份程式先定義 helper,再讓 solve 使用它;不要讀鍵盤、改寫測資,或把輸入寫死。測試至少包含一般情況、空資料(題目允許時)與邊界。

PYTHON程式碼
def add_tax(price, fee):
    return price + fee

def solve(price, fee):
    return add_tax(price, fee)

print(solve(30, 5))
print(solve(0, 0))
預期輸出
35
0

WHEN SOMETHING GOES WRONG

遇到錯誤,先檢查這裡

忘記括號,拿到函式本身

greet 是函式;greet("小芽") 才是呼叫結果。先確認自己現在需要的是功能,還是執行後的資料。

只在某個分支 return

檢查所有輸入走過的路徑。某個分支沒回傳,就可能出現你沒預期的 None。

第一組測資正確,下一組受到前次影響

檢查共用的可變預設值或全域清單。每次呼叫應依當次參數開始計算,除非題目特別要求保留狀態。

PAUSE AND TRY

先不要急著看別人的寫法

  1. 設計一個只判斷偶數的函式,再讓另一個函式統計清單中的偶數。
  2. 用自己的話說明 print(5) 與 return 5 的差別。
  3. 一個函式需要三個參數,你如何檢查呼叫時的順序是否正確?

先用紙筆預測,再改動範例中的數字或文字。結果與預期不同時,找出最早開始不同的那一步。

把這幾件事帶走

  • 參數是輸入,return 是輸出。
  • 函式命名要能表達它完成的事情。
  • 獨立測試小函式,再組合成 solve。

FROM READING TO PRACTICE

用三道免費題,練習本章觀念

先做簡單題確認語法,再把幾個步驟組合起來。三題都來自本章主題的新版免費題庫,難度表示需要組合的基本概念。

延伸閱讀:Python 官方文件

以下是本章查證使用的官方資料。可以先完成入門練習,再回來查閱更完整的參數與說明。