文章目錄
- 為什么要使用函數?
- 函數的定義 (`def`)
- 函數的調用
- 函數參數 (Parameters vs Arguments)
- 返回值 (`return`)
- 變量作用域 (簡要了解)
- 總結
- 練習題
- 練習題答案
- **創作不易,請大家點贊加收藏,關注我,持續更新教程!**
到目前為止,我們已經學習了基本的數據類型、集合類型以及控制程序流程的條件語句和循環。隨著程序越來越復雜,我們可能會發現自己反復編寫相同的代碼塊來執行特定任務。這不僅低效,還會導致代碼難以閱讀和維護。
函數就是解決這個問題的重要工具。它們允許我們將一段代碼封裝起來,賦予一個名字,然后在需要的時候多次調用。本篇博客將深入講解如何定義自己的函數、如何調用它們,以及如何使用 return
語句從函數中獲取結果。
為什么要使用函數?
使用函數的好處多多:
- 代碼重用 (Reusability): 避免重復編寫相同的代碼塊。遵循 DRY (Don’t Repeat Yourself) 原則。
- 模塊化 (Modularity): 將程序分解成更小、更易于管理和理解的部分。每個函數負責一個特定的任務。
- 提高可讀性 (Readability): 通過有意義的函數名,代碼變得更容易理解其目的。
- 易于維護和調試 (Maintainability & Debugging): 當需要修改或修復某個功能的代碼時,只需在一個地方(函數定義處)進行修改。如果出現錯誤,更容易定位問題在哪個函數中。
函數的定義 (def
)
在 Python 中,使用 def
關鍵字來定義一個函數。定義函數的基本結構如下:
def function_name(parameter1, parameter2, ...):"""這里是函數的文檔字符串 (Docstring)。解釋函數的功能、參數和返回值。"""# 函數體 - 執行任務的代碼塊# ...# return value # 可選的返回值
def
關鍵字: 標記著一個函數的定義開始。function_name
: 函數的名字。需要遵循 Python 的命名規則(通常使用小寫字母和下劃線_
組合,稱為 snake_case)。函數名應該能夠清晰地表明函數的功能。- 圓括號
()
: 緊跟在函數名后面。里面可以包含參數 (Parameters),用于接收外部傳遞進來的數據。如果沒有參數,圓括號也不能省略。 - 冒號
:
: 標記著函數頭部的結束,函數體即將開始。 - 文檔字符串 (Docstring): 使用三引號
""" """
或''' '''
包圍起來的一段文本。它應該在函數頭部的下一行,用于詳細說明函數的作用。這是 Python 的一個重要特性,可以通過help(function_name)
或function_name.__doc__
查看。編寫良好的文檔字符串是好習慣。 - 函數體: 縮進的代碼塊,包含了函數執行的實際操作。
return
語句: 用于指定函數執行完畢后返回給調用者的值。是可選的。
示例: 定義一個簡單的函數,它不接受參數,也不返回值,只打印一條消息。
def greet():"""這是一個簡單的打招呼函數。"""print("Hello, welcome to Python functions!")print("This function does not take arguments and does not return a value.")
上面的代碼只是定義了一個函數,它還沒有被執行。
函數的調用
定義函數后,要讓它執行里面的代碼,就需要調用它。調用函數非常簡單,只需要使用函數名后面加上圓括號 ()
即可。如果函數定義時有參數,調用時需要在圓括號中提供相應的實參 (Arguments)。
# 調用上面定義的 greet 函數
greet()
greet() # 函數可以被多次調用
輸出:
Hello, welcome to Python functions!
This function does not take arguments and does not return a value.
Hello, welcome to Python functions!
This function does not take arguments and does not return a value.
函數參數 (Parameters vs Arguments)
- 參數 (Parameters): 在函數定義時,圓括號中列出的變量名。它們是函數內部使用的占位符,代表函數期望接收的數據。
- 實參 (Arguments): 在函數調用時,傳遞給函數參數的實際值。
# 定義一個接受一個參數的函數
def greet_person(name):"""向指定名字的人打招呼。Args:name: 要打招呼的人的名字 (字符串)。"""print(f"Hello, {name}!")# 調用函數,并傳遞實參
greet_person("Alice") # "Alice" 是傳遞給 name 參數的實參
greet_person("Bob") # "Bob" 是傳遞給 name 參數的實參
輸出:
Hello, Alice!
Hello, Bob!
一個函數可以有多個參數,調用時需要按照參數定義的順序傳遞實參。
# 定義一個接受兩個參數的函數
def add_numbers(a, b):"""計算兩個數字的和。Args:a: 第一個數字。b: 第二個數字。"""sum_result = a + bprint(f"{a} + {b} = {sum_result}")# 調用函數,傳遞兩個實參
add_numbers(5, 3) # a=5, b=3
add_numbers(10, 20) # a=10, b=20
輸出:
5 + 3 = 8
10 + 20 = 30
調用帶有參數的函數時,必須提供正確數量的實參(對于目前我們學習的必需參數)。
返回值 (return
)
函數的一個重要作用是執行計算并將結果返回給調用者。使用 return
語句來實現。
return value
: 函數執行到return
語句時,會立即停止執行,并將value
返回給調用者。- 如果函數沒有
return
語句,或者只有不帶值的return
,它會隱式地返回特殊的值None
。 None
是 Python 中表示“無”或“空”的一個特殊對象。
# 定義一個函數,使用 return 返回計算結果
def multiply(x, y):"""計算兩個數字的乘積并返回結果。Args:x: 第一個數字。y: 第二個數字。Returns:兩個數字的乘積。"""product = x * yreturn product # 返回計算得到的乘積# 調用函數,并用變量接收返回值
result = multiply(4, 6)
print(f"乘積是: {result}") # 輸出: 乘積是: 24another_result = multiply(2.5, 4)
print(f"另一個乘積是: {another_result}") # 輸出: 另一個乘積是: 10.0
注意: return
語句一旦執行,函數就會結束。return
后面的代碼將不會被執行。
def example_return(num):if num > 10:return "大于 10" # 如果 num > 10,函數在這里結束print("數字不大于 10") # 如果 num <= 10,這行會執行return "小于或等于 10" # 然后返回這個值print(example_return(15)) # 輸出: 大于 10
print(example_return(8)) # 輸出: 數字不大于 10\n小于或等于 10
隱式返回 None
:
def print_message(msg):"""只打印消息,沒有 return 語句。"""print(msg)# 隱式地返回 Nonereturn_value = print_message("Hello")
print(f"函數返回的值是: {return_value}") # 輸出: Hello\n函數返回的值是: None
返回多個值:
Python 函數可以看似返回多個值,實際上,它是將多個值封裝在一個元組 (tuple) 中返回。
def get_name_and_age():"""返回名字和年齡。"""name = "Charlie"age = 25return name, age # 實際上返回 ('Charlie', 25)info = get_name_and_age()
print(f"獲取到的信息是: {info}") # 輸出: 獲取到的信息是: ('Charlie', 25)
print(f"類型是: {type(info)}") # 輸出: 類型是: <class 'tuple'># 可以使用元組解包來分別獲取返回值
person_name, person_age = get_name_and_age()
print(f"名字: {person_name}, 年齡: {person_age}") # 輸出: 名字: Charlie, 年齡: 25
變量作用域 (簡要了解)
在函數內部定義的變量(包括參數)通常是局部變量 (Local Variables)。它們只存在于函數執行期間,函數結束后就會被銷毀,在函數外部無法訪問。
def my_function():x = 10 # x 是局部變量print(f"函數內部的 x: {x}")my_function()
# print(x) # 這會引發 NameError,因為 x 在函數外部不存在
全局變量(在函數外部定義的變量)可以在函數內部訪問,但不建議在函數內部直接修改全局變量,除非使用 global
關鍵字(但這通常是初學者應盡量避免的高級用法)。將數據通過參數傳遞進函數,通過返回值傳出,是更好的實踐。
總結
函數是 Python 中組織代碼、實現重用和模塊化的核心工具。本篇我們學習了:
- 使用
def
關鍵字定義函數。 - 理解參數 (Parameters) 和實參 (Arguments) 的區別。
- 如何調用函數來執行其代碼。
- 使用
return
語句從函數中返回一個或多個值。 - 函數沒有顯式返回值時默認返回
None
。 - 函數內部變量的局部作用域概念。
- 編寫文檔字符串說明函數功能。
練習題
嘗試獨立完成以下練習題,并通過答案進行對照:
-
簡單函數定義與調用:
- 定義一個函數
print_hello()
,它不接受參數,只打印 “Hello, Python!”。調用這個函數。
- 定義一個函數
-
帶參數的函數:
- 定義一個函數
say_greeting(name)
,它接受一個字符串參數name
,并打印 “Hello, [name]!”。調用這個函數,傳入你的名字。
- 定義一個函數
-
帶返回值的函數:
- 定義一個函數
calculate_square(number)
,它接受一個數字參數number
,計算并返回這個數字的平方。調用這個函數,并打印返回值。 - 定義一個函數
is_even(number)
,它接受一個整數參數number
,如果數字是偶數返回True
,否則返回False
。調用這個函數測試幾個數字。
- 定義一個函數
-
返回多個值的函數:
- 定義一個函數
divide_and_remainder(a, b)
,它接受兩個數字a
和b
,計算a
除以b
的商和余數,并同時返回這兩個結果(作為一個元組)。調用這個函數,并使用元組解包分別獲取商和余數,然后打印。
- 定義一個函數
-
結合循環和條件的函數:
- 定義一個函數
count_vowels(text)
,它接受一個字符串參數text
,遍歷字符串,統計其中元音字母(a, e, i, o, u,不區分大小寫)的數量,并返回數量。調用這個函數測試一些字符串。
- 定義一個函數
-
帶文檔字符串的函數:
- 為你前面定義的任何一個函數添加一個清晰的文檔字符串,說明其功能、參數和返回值。然后使用
help()
函數查看你寫的文檔。
- 為你前面定義的任何一個函數添加一個清晰的文檔字符串,說明其功能、參數和返回值。然后使用
練習題答案
1. 簡單函數定義與調用:
# 1. 簡單函數定義與調用
def print_hello():"""打印一條簡單的問候信息。"""print("Hello, Python!")# 調用函數
print_hello()
2. 帶參數的函數:
# 2. 帶參數的函數
def say_greeting(name):"""向指定名字的人打招呼。Args:name: 要打招呼的人的名字 (字符串)。"""print(f"Hello, {name}!")# 調用函數
say_greeting("Alice")
say_greeting("Bob")
3. 帶返回值的函數:
# 3.1 計算平方并返回
def calculate_square(number):"""計算并返回一個數字的平方。Args:number: 需要計算平方的數字。Returns:number 的平方。"""return number ** 2# 調用并打印返回值
result1 = calculate_square(5)
print(f"5 的平方是: {result1}")result2 = calculate_square(3.5)
print(f"3.5 的平方是: {result2}")# 3.2 判斷奇偶數并返回布爾值
def is_even(number):"""判斷一個整數是否是偶數。Args:number: 需要判斷的整數。Returns:如果數字是偶數返回 True,否則返回 False。"""return number % 2 == 0# 調用并測試
print(f"4 是偶數嗎? {is_even(4)}")
print(f"7 是偶數嗎? {is_even(7)}")
print(f"0 是偶數嗎? {is_even(0)}")
4. 返回多個值的函數:
# 4. 返回多個值的函數
def divide_and_remainder(a, b):"""計算兩個數字的商和余數。Args:a: 被除數。b: 除數 (不能為 0)。Returns:一個包含商和余數的元組 (quotient, remainder)。如果 b 為 0,返回 None。"""if b == 0:print("錯誤: 除數不能為零。")return None # 或者根據需要處理錯誤quotient = a // b # 整數除法獲取商remainder = a % b # 獲取余數return quotient, remainder # 返回一個元組# 調用并解包返回值
result_tuple = divide_and_remainder(10, 3)if result_tuple is not None: # 檢查返回值是否為 Nonequotient, remainder = result_tuple # 元組解包print(f"10 除以 3 的商是: {quotient}, 余數是: {remainder}")divide_and_remainder(5, 0) # 測試除數為零的情況
5. 結合循環和條件的函數:
# 5. 結合循環和條件的函數
def count_vowels(text):"""統計字符串中元音字母的數量。Args:text: 輸入的字符串。Returns:字符串中元音字母 (a, e, i, o, u, 不區分大小寫) 的數量。"""vowels = "aeiouAEIOU" # 元音字母集合vowel_count = 0for char in text: # 遍歷字符串中的每個字符if char in vowels: # 檢查字符是否在元音字母集合中vowel_count += 1return vowel_count# 調用并測試
sentence1 = "Hello World"
count1 = count_vowels(sentence1)
print(f"'{sentence1}' 中的元音字母數量: {count1}")sentence2 = "Python Programming"
count2 = count_vowels(sentence2)
print(f"'{sentence2}' 中的元音字母數量: {count2}")
6. 帶文檔字符串的函數:
選擇上面任意一個函數,確保你已經添加了文檔字符串,然后運行以下代碼:
# 假設你已經為 calculate_square 函數添加了文檔字符串
# 運行以下代碼查看文檔
help(calculate_square)# 或者直接訪問 __doc__ 屬性
print("\n--- 通過 __doc__ 屬性訪問文檔字符串 ---")
print(calculate_square.__doc__)
運行 help(calculate_square)
應該會輸出你為 calculate_square
函數編寫的文檔字符串內容(通常會格式化得更漂亮)。