目錄
一、為什么需要函數?
1. 拒絕重復造輪子
2. 讓代碼像句子一樣可讀
3. 隔離變化,降低維護成本
二、函數的定義:編寫高質量函數的5個要素
基本語法框架
1. 函數命名的黃金法則(PEP8規范)
2. 不可或缺的文檔字符串(Docstring)
3. 參數設計的藝術
4. 函數體的單一職責原則
5. 返回值的清晰表達
三、函數調用:3種傳遞參數的方式
1. 位置參數(最常用)
2. 關鍵字參數(提升可讀性)
3. 混合使用(位置參數在前)
四、形參VS實參:參數的"前世今生"
生動案例:快遞柜的故事
參數傳遞的注意事項
五、實戰進階:溫度轉換工具函數
六、避坑指南:初學者常犯的5個錯誤
1. 縮進錯誤(IndentationError)
2. 參數數量不匹配(TypeError)
3. 忽略返回值
4. 函數名拼寫錯誤
5. 在函數定義前調用函數
七、總結與練習
一、為什么需要函數?
在編程中,函數就像一個"功能盒子"——把重復執行的代碼塊打包起來,需要時直接"調用"這個盒子即可。想象你每天早上都要做三件事:刷牙、洗臉、吃早餐。如果把這三個動作寫成代碼,沒有函數的話,每次都要重復寫三遍相同的步驟;而有了函數,你可以把它們分別定義成brush_teeth()
、wash_face()
、eat_breakfast()
三個函數,之后只需依次調用這三個函數名即可。
函數的核心目的:
- 代碼復用:避免重復編寫相同邏輯
- 模塊化:將復雜問題拆解為小任務
- 可讀性:用函數名直接體現代碼功能
函數就是代碼世界的"工序卡",解決三大核心問題:
1. 拒絕重復造輪子
沒有函數的代碼:
# 計算三個矩形的面積
print(5*3) # 第一個矩形
print(4*6) # 第二個矩形
print(7*2) # 第三個矩形
有函數的代碼:
def calculate_rect_area(width, height):
return width * heightprint(calculate_rect_area(5,3)) # 復用相同邏輯
print(calculate_rect_area(4,6))
print(calculate_rect_area(7,2))
2. 讓代碼像句子一樣可讀
# 不好的代碼:一堆數字和符號
if score >= 90 and score <= 100:
print("優秀")# 好的代碼:函數名即注釋
def is_excellent(score):
return 90 <= score <= 100if is_excellent(score):
print("優秀")
3. 隔離變化,降低維護成本
當計算面積的公式需要修改(比如增加單位轉換),只需修改函數內部,而不用在代碼中到處查找width*height
的片段。
二、函數的定義:編寫高質量函數的5個要素
基本語法框架
def 函數名(參數列表):"""函數文檔字符串(可選但推薦)"""# 函數體(縮進4個空格)return 返回值 # 可選
1. 函數命名的黃金法則(PEP8規范)
- 全部小寫,用下劃線分隔:
calculate_area
??,CalculateArea
?? - 使用動詞或動詞短語:
get_user_info
??,user_info
?? - 避免單字母命名(除常見約定:
i
/j
循環變量,x
/y
坐標)
2. 不可或缺的文檔字符串(Docstring)
def calculate_circle_area(radius):
"""計算圓的面積參數:
radius (float): 圓的半徑,必須大于0返回:
float: 圓的面積(πr2)異常:
ValueError: 當半徑為負數時觸發
"""
if radius < 0:
raise ValueError("半徑不能為負數")
return 3.14159 * radius **2
技巧:在PyCharm等IDE中輸入
"""
按回車,會自動生成文檔字符串模板
3. 參數設計的藝術
- 必要參數:必須傳遞的參數(如
radius
) - 默認參數:帶有默認值的參數(
def greet(name="Guest")
) - 參數順序:重要參數放前面,可選參數放后面
4. 函數體的單一職責原則
一個函數只做一件事!以下是反面教材:
def bad_function(user_id):
# 同時做三件事:查詢用戶、發郵件、記錄日志
user = db.query(user_id)
send_email(user.email)
log_activity(user_id)
return user
5. 返回值的清晰表達
- 始終返回同一類型(避免有時返回列表,有時返回None)
- 復雜邏輯用多個return提前退出,比嵌套if更清晰:
def get_grade(score):
if score < 0 or score > 100:
return "無效分數" # 提前返回異常情況
if score >= 90:
return "A"
if score >= 80:
return "B"
# ...其他分數段
三、函數調用:3種傳遞參數的方式
1. 位置參數(最常用)
按參數定義順序傳遞:
def divide(dividend, divisor):
return dividend / divisorresult = divide(10, 2) # dividend=10, divisor=2
2. 關鍵字參數(提升可讀性)
明確指定參數名,順序可以打亂:
result = divide(dividend=10, divisor=2)
# 等價于
result = divide(divisor=2, dividend=10)
3. 混合使用(位置參數在前)
def greet(title, name):
return f"{title}. {name}"greet("Mr", name="Smith") # 正確:位置參數在前
# greet(title="Mr", "Smith") # 錯誤:關鍵字參數不能在位置參數前
四、形參VS實參:參數的"前世今生"
維度 | 形參(形式參數) | 實參(實際參數) |
---|---|---|
位置 | 函數定義時?def func(x, y) | 函數調用時?func(3, 5) |
本質 | 函數內部的局部變量聲明 | 傳遞給函數的具體值/變量 |
生命周期 | 函數調用期間存在 | 遵循自身的變量作用域 |
生動案例:快遞柜的故事
- 形參:快遞柜上的"格子A"、"格子B"(定義了存放位置)
- 實參:你放入格子A的"手機"、格子B的"鑰匙"(實際存放的物品)
- 函數調用:快遞柜系統執行"存儲(格子A, 手機)"操作
參數傳遞的注意事項
def add_one(num):
num += 1 # 形參的修改不影響實參x = 5
add_one(x)
print(x) # 輸出:5(x的值未改變)
五、實戰進階:溫度轉換工具函數
讓我們構建一個完整的溫度轉換模塊,包含:
- 攝氏度轉華氏度
- 華氏度轉攝氏度
- 參數驗證功能
def celsius_to_fahrenheit(celsius):
"""攝氏度轉華氏度 (°F = °C × 9/5 + 32)"""
if not isinstance(celsius, (int, float)):
raise TypeError("溫度必須是數字")
if celsius < -273.15:
raise ValueError("溫度不能低于絕對零度(-273.15°C)")
return celsius * 9/5 + 32def fahrenheit_to_celsius(fahrenheit):
"""華氏度轉攝氏度 (°C = (°F - 32) × 5/9)"""
if not isinstance(fahrenheit, (int, float)):
raise TypeError("溫度必須是數字")
if fahrenheit < -459.67:
raise ValueError("溫度不能低于絕對零度(-459.67°F)")
return (fahrenheit - 32) * 5/9# 使用示例
try:
temp_f = celsius_to_fahrenheit(25)
print(f"25°C = {temp_f:.1f}°F") # 輸出:25°C = 77.0°Ftemp_c = fahrenheit_to_celsius(77)
print(f"77°F = {temp_c:.1f}°C") # 輸出:77°F = 25.0°C
except (TypeError, ValueError) as e:
print(f"轉換失敗:{e}")
六、避坑指南:初學者常犯的5個錯誤
1. 縮進錯誤(IndentationError)
def my_func():
print("Hello") # 錯誤:函數體沒有縮進
2. 參數數量不匹配(TypeError)
def add(a, b):
return a + badd(1) # 錯誤:缺少1個位置參數
3. 忽略返回值
def calculate_sum(a, b):
result = a + b # 錯誤:沒有return語句total = calculate_sum(3, 5)
print(total) # 輸出:None
4. 函數名拼寫錯誤
def print_greeting():
print("Hello")print_greetng() # 錯誤:函數名拼寫錯誤(少了一個i)
5. 在函數定義前調用函數
my_func() # 錯誤:調用時函數還未定義def my_func():
print("Hello")
七、總結與練習
函數是編程的基礎模塊,掌握其定義規范、調用邏輯和參數傳遞機制,是寫出簡潔、高效、可維護代碼的關鍵。后續將深入學習參數進階用法(默認參數、不定長參數等)和函數作用域,進一步提升代碼靈活性。