Skip to content

Python 函數入門:參數、返回值與進階技巧

函數 (function) 是一個非常核心的概念,如果你需要重複執行某一段相同的程式碼,不斷複製貼上會讓你的程式變得冗長且難以維護。函數能重複執行的問題,它把一組程式碼封裝起來,給它一個名字,之後可以透過這個名字來重複使用這段程式碼。這篇文章將帶你了解 Python 中的 function。

🧩 函數的基本結構

Python 中定義函數非常簡單,主要使用 def 關鍵字。 一個基本的函數結構包含:

  1. def 關鍵字:告訴 Python 你要定義一個函數。
  2. 函數名稱 (Function Name):你自己取的名稱,用來識別和呼叫函數。習慣上使用小寫字母和底線 (snake_case),例如 my_function
  3. 括號 ():緊跟在函數名稱後面,裡面可以放參數 (parameters)。
  4. 冒號 ::表示函數定義的開始。
  5. 縮排的程式碼區塊 (Indented Code Block):這就是函數的主體 (function body),也就是函數要執行的動作。
  6. (選擇性) 文件字串 (Docstring):用三個引號 """docstring""" 包起來的字串,用來說明函數的功能、參數和返回值。
python
def greet():
    """這是一個簡單的打招呼函數。"""
    print("Hello, Python!")

# 呼叫函數
greet()

在這個例子中,greet 就是函數名稱。當你執行 greet() 時,它就會印出 "Hello, Python!"。

📥 參數與引數 (Parameters and Arguments)

很多時候,函數需要一些外部的資料才能完成工作。這時候就需要用到參數和引數。

  • 參數 (Parameters):在定義函數時,放在括號 () 裡面的變數名稱。它們像是函數內部的佔位符。
  • 引數 (Arguments):在呼叫函數時,傳遞給函數的實際值。
python
def greet_user(name):  # 'name' 是一個參數
    """根據提供的名字打招呼。"""
    print(f"你好, {name}!")

greet_user("小明")  # "小明" 是一個引數
greet_user("小華")  # "小華" 是另一個引數

位置引數 (Positional Arguments)

引數會按照順序對應到參數。

python
def describe_pet(animal_type, pet_name):
    """顯示寵物的資訊。"""
    print(f"我有一隻 {animal_type}。")
    print(f"我的 {animal_type} 叫做 {pet_name.title()}。")

describe_pet("倉鼠", "毛毛")

關鍵字引數 (Keyword Arguments)

你可以明確指定引數要對應到哪個參數,這樣就不用擔心順序問題。

python
describe_pet(animal_type="貓咪", pet_name="花花")
describe_pet(pet_name="皮蛋", animal_type="狗狗") # 順序可以調換

預設參數值 (Default Parameter Values)

你可以為參數設定預設值。如果在呼叫函數時沒有提供該參數的引數,就會使用預設值。

python
def greet_default(name="訪客"): # 'name' 有預設值 "訪客"
    print(f"你好, {name}!")

greet_default("小陳") # 輸出: 你好, 小陳!
greet_default()      # 輸出: 你好, 訪客!

📤 函數的返回值 Return Values

函數不僅可以執行動作,還可以回傳結果給呼叫它的地方。這是透過 return 關鍵字來實現的。

返回 None

如果函數沒有明確的 return 語句,或者 return 後面沒有接任何值,它會自動返回一個特殊的值 NoneNone 在 Python 中表示「沒有值」或「空值」。當然,你也可以自行返回 None

python
def print_sum(a, b):
    result = a + b
    print(f"總和是: {result}") # 這個函數只印出結果,沒有返回值

sum_value = print_sum(5, 3)
print(f"函數返回值: {sum_value}") # 輸出: 函數返回值: None

返回單個值

使用 return 關鍵字可以讓函數回傳一個計算結果或特定的值。

python
def add_numbers(x, y):
    """回傳兩個數字的總和。"""
    return x + y

result = add_numbers(10, 5)
print(f"10 + 5 的結果是: {result}") # 輸出: 10 + 5 的結果是: 15

一旦執行到 return 語句,函數就會立即終止並回傳值。

返回多個值

Python 函數可以方便地一次返回多個值。實際上,Python 會將這些值打包成一個元組 (tuple) 返回。

python
def get_name_and_age():
    name = "Paul"
    age = 20
    return name, age # 返回一個元組 ('Paul', 20)

# 可以用多個變數來接收返回的多個值
user_name, user_age = get_name_and_age()
print(f"姓名: {user_name}, 年齡: {user_age}") # 輸出: 姓名: Paul, 年齡: 20

# 或者直接接收整個元組
info = get_name_and_age()
print(f"資料: {info}") # 輸出: 資訊: ('Paul', 20)
print(f"元組 (tuple) 的第一個元素: {info[0]}") # 輸出: 元組 (tuple) 的第一個元素: Paul

🎁 函數作為物件 Functions as Objects

在 Python 中,函數是「一等公民 (first-class citizens)」。這代表函數和其他資料類型 (例如數字、字串、列表) 一樣,擁有同等的地位。你可以:

  1. 將函數賦值給變數。
  2. 將函數作為引數傳遞給其他函數。
  3. 讓函數作為另一個函數的返回值 (這個比較進階,這裡先不詳述)。
python
def say_hello():
    return "Hello!"

# 1. 將函數賦值給變數
greet_message_func = say_hello
print(greet_message_func()) # 輸出: Hello!

# 2. 將函數作為引數傳遞給其他函數
def execute_function(func_to_run):
    print("準備執行函數...")
    result = func_to_run()
    print(f"函數執行結果: {result}")

execute_function(say_hello)
# 輸出:
# 準備執行函數...
# 函數執行結果: Hello!

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def calculate(operation_func, x, y):
    return operation_func(x, y)

result_add = calculate(add, 10, 3)
result_subtract = calculate(subtract, 10, 3)

print(f"10 + 3 = {result_add}")       # 輸出: 10 + 3 = 13
print(f"10 - 3 = {result_subtract}") # 輸出: 10 - 3 = 7

這種特性讓 Python 的函數非常靈活,是許多進階編程技巧 (如裝飾器 Decorators) 的基礎。

🪆 嵌套函數 Nested Functions

Python 允許你在一個函數內部定義另一個函數,這就是所謂的嵌套函數或內部函數 (inner function)。 內部函數只能在其外部函數 (outer function) 的作用域內被存取和呼叫。內部函數可以存取外部函數的變數。

python
def outer_function(text):
    message = text # 外部函數的變數

    def inner_function():
        # 內部函數可以存取外部函數的 'message' 變數
        print(f"內部訊息: {message.upper()}")

    print("準備從外部函數呼叫內部函數...")
    inner_function() # 在外部函數中呼叫內部函數

outer_function("hello world")
# 輸出:
# 準備從外部函數呼叫內部函數...
# 內部訊息: HELLO WORLD

這對於封裝輔助功能、實現閉包 (closures) 和裝飾器等都很有用。

💡 型別提示 Type Hints

Python 是一種動態型別語言,這代表你在定義變數或函數參數時,不需要事先聲明它們的型別。Python 直譯器會在執行時期自動推斷型別。 然而,從 Python 3.5 開始,引入了型別提示 (Type Hints) 的功能。它允許你為函數參數和返回值「建議」型別。

型別提示的語法:

  • 參數型別提示:parameter_name: type
  • 返回值型別提示:def function_name(...) -> return_type:
python
def greet_typed(name: str) -> str:
    return f"Hello, {name}"

def add_typed(a: int, b: int) -> int:
    return a + b

greeting = greet_typed("Python 開發者")
sum_result = add_typed(5, 10)

print(greeting)      # 輸出: Hello, Python 開發者
print(sum_result)    # 輸出: 15

型別提示的好處:

  1. 提升程式碼可讀性:其他人 (或未來的你) 可以更容易理解函數期望接收什麼型 welchen 的資料,以及它會回傳什麼型 welchen 的資料。
  2. 編輯器支援:現代的程式碼編輯器 (如 VS Code, PyCharm) 可以利用型別提示來提供更好的自動完成 (autocomplete) 功能和即時的型別檢查。如果傳遞了不符合提示的型別,編輯器通常會顯示警告。
  3. 提早發現潛在錯誤:雖然 Python 在執行時期不會因為型別不符提示而阻止程式運行 (除非操作本身不合法),但編輯器的警告可以幫助你在開發階段就注意到可能的型別錯誤,從而提早修正。

重要提醒:

  • 型別提示是完全選擇性的 (optional)。你可以選擇用,也可以選擇不用。
  • Python 執行時期不會強制執行型別提示。即使你傳遞了與提示不符的型別的引數,只要程式碼在邏輯上可以執行,它仍然會運行。型別提示主要用於靜態分析工具和開發者之間的溝通。
    python
    def process_data(data: list) -> None:
        # 假設這裡期望 data 是一個列表
        if isinstance(data, list): # 實際運行時的檢查還是需要的
            for item in data:
                print(item)
        else:
            print(f"警告: 傳入的 data (值: {data}) 並非列表型別!")
    
    process_data([1, 2, 3]) # 正常運作
    process_data("這不是列表") # 執行時期會印出警告,但不會因為型別提示而直接報錯
                            # 編輯器層面可能會在你寫 process_data("...") 時就給出警告
    型別提示就像是給程式碼加了註解,告訴編輯器和其他開發者你的意圖。如果你堅持傳遞錯誤的型別,程式碼仍然會嘗試執行,只是編輯器可能會提醒你「這樣做可能不是個好主意」。

✍️ Lambda 函數簡介

Lambda 函數是一種小型的、匿名的、單行表達式的函數。它們使用 lambda 關鍵字定義,而不是 def。 Lambda 函數的語法是:lambda arguments: expression

它們通常用在需要一個簡單函數,但又不想另外用 def 定義一個完整函數的場合。

python
# 一個簡單的加法 lambda 函數
add_lambda = lambda x, y: x + y
result = add_lambda(5, 3)
print(f"Lambda 加法結果: {result}") # 輸出: Lambda 加法結果: 8

# Lambda 常用於排序的 key
points = [(1, 2), (3, 1), (5, -4), (0, 0)]
# 根據每個元組的第二個元素排序
points.sort(key=lambda point: point[1])
print(f"排序後的點: {points}") # 輸出: 排序後的點: [(5, -4), (0, 0), (3, 1), (1, 2)]

Lambda 函數功能有限,它只能包含一個表達式,不能有多行語句。對於初學者來說,了解它們的存在即可,更複雜的函數還是建議使用 def 來定義,以保持程式碼的清晰度。

📝 總結

函數是 Python 編程中不可或缺的工具。透過定義和使用函數,你可以:

  • 組織程式碼,使其更具結構化和模組化。
  • 重複使用程式碼,避免不必要的複製貼上。
  • 提高程式碼的可讀性和可維護性。

本文介紹了函數的基本定義、參數與引數的傳遞、不同類型的返回值、函數作為物件的特性、嵌套函數的概念,以及方便的型別提示和簡潔的 Lambda 函數。掌握這些基礎知識,將為你學習更進階的 Python 編程技巧打下堅實的基礎。多練習編寫和使用函數,你會發現它們的強大之處!

📚 參考資料

KF Software House