Python 函數基本介紹(詳細版)?
文章目錄
- Python 函數基本介紹(詳細版)?
- 前言
- 一、函數的創建?
- 1.1 函數名的命名規則?
- 1.2 函數的創建?
- 1.3 函數的調用?
- 二、函數的參數?
- 2.1 形參和實參?
- 2.2 位置參數?
- 2.3 關鍵字參數?
- 2.4 默認參數?
- 2.5 不定長參數?
- 2.6 參數組合使用?
- 三、函數的返回值?
- 四、匿名函數?
- 五、函數的作用域?
- 六、嵌套函數?
- 七、閉包?
- 八、遞歸函數?
- 總結
前言
函數是 Python 編程的核心構建塊,它將特定功能的代碼封裝成獨立單元,不僅能減少重復代碼,還能讓程序結構更清晰、易于維護。深入理解函數的各項特性,是編寫高質量 Python 代碼的基礎。?
一、函數的創建?
函數創建的核心是用def關鍵字定義一個可復用的代碼塊,其完整結構包含函數名、參數列表、文檔字符串、函數體和返回值,每個部分都有明確的作用。?
1.1 函數名的命名規則?
函數名需遵循 Python 標識符命名規范:?
- 只能包含字母、數字和下劃線?
- 不能以數字開頭?
- 不能使用 Python 關鍵字(如def、if等)?
- 建議使用小寫字母,多個單詞用下劃線連接(蛇形命名法),如calculate_average
1.2 函數的創建?
創建函數使用def關鍵字,基本語法為:?
def 函數名(參數):函數體return 返回值
例如,創建一個計算兩數之和的函數:?
def add(a, b):?result = a + b?return result
這里的add是函數名,a和b是參數,函數體是計算兩數之和并將結果賦給result,最后通過return返回result。?
1.3 函數的調用?
調用函數只需使用 “函數名 (參數)” 的形式。以上面的add函數為例:?
sum_result = add(3, 5)?
print(sum_result) # 輸出:8?
當調用add(3, 5)時,函數內部的a被賦值為 3,b被賦值為 5,經過計算后返回 8,然后將 8 賦給sum_result并打印出來。?
二、函數的參數?
函數的參數是函數與外部交互的橋梁,根據傳遞和定義方式的不同,可分為多種類型。其中,形參和實參是參數的基本概念。?
2.1 形參和實參?
形參(形式參數):在定義函數時,括號中列出的參數稱為形參,它們只是函數定義時用來接收外部傳入數據的 “占位符”,沒有具體的值。
例如在def add(a, b):中,a和b就是形參。?
實參(實際參數):在調用函數時,括號中傳入的具體數據稱為實參,它們會被賦值給對應的形參。
例如在add(3, 5)中,3和5就是實參,分別賦值給形參a和b。?
形參和實參的關系是:實參是形參的具體值,在函數調用時,實參的值會傳遞給形參,供函數體使用。?
2.2 位置參數?
位置參數是最常見的參數類型,參數按照位置順序傳遞,實參與形參必須一一對應,數量也必須一致。如add(3,5)中,3 傳給a,5 傳給b。如果參數數量不匹配,會報錯,例如add(3)會提示缺少一個位置參數。?
2.3 關鍵字參數?
調用時指定參數名(形參名),可改變參數順序,使代碼更具可讀性。例如:?
sum_result = add(b=5, a=3)?
print(sum_result) # 輸出:8?
這里明確指定b為 5,a為 3,雖然順序與函數定義時不同,但仍能正確計算結果。使用關鍵字參數時,關鍵字必須是函數定義時的形參名,否則會報錯。?
2.4 默認參數?
定義函數時給形參設置默認值,調用時可省略該參數,若不省略則使用傳遞的實參值。示例:?
def greet(name, greeting="Hello"):?print(f"{greeting}, {name}!")?
?
greet("Alice") # 輸出:Hello, Alice!?
greet("Bob", "Hi") # 輸出:Hi, Bob!?
在greet函數中,greeting是設置了默認值 “Hello” 的形參,當調用greet(“Alice”)時,沒有傳遞對應greeting的實參,就使用默認值;調用greet(“Bob”, “Hi”)時,傳遞了實參 “Hi”,則使用該值。需要注意的是,默認參數必須放在位置參數之后,否則會報錯,例如def greet(greeting=“Hello”, name):是錯誤的。?
2.5 不定長參數?
當不確定需要傳遞多少個實參時,可以使用不定長參數,它們能接收任意數量的實參。?
*args:接收任意數量的位置實參,以元組形式存儲,args是約定俗成的名稱,也可以使用其他名稱,但建議使用args。?
def sum_numbers(*args):?total = 0?for num in args:?total += num?return total?
?
print(sum_numbers(1, 2, 3)) # 輸出:6?
print(sum_numbers(4, 5, 6, 7)) # 輸出:22?
?
在sum_numbers函數中,*args接收了傳遞的所有位置實參,然后通過循環將它們相加。?
**kwargs:接收任意數量的關鍵字實參,以字典形式存儲,其中鍵是參數名(形參名),值是參數值(實參值),kwargs是約定俗成的名稱,也可使用其他名稱,建議使用kwargs。?
def print_info(** kwargs):?for key, value in kwargs.items():?print(f"{key}: {value}")?
?
print_info(name="Alice", age=20, gender="female")?
# 輸出:?
# name: Alice?
# age: 20?
# gender: female?
這里**kwargs接收了name、age、gender三個關鍵字實參,并以字典的形式遍歷輸出。?
2.6 參數組合使用?
在定義函數時,多種參數可以組合使用,但需要遵循一定的順序:位置參數在前,然后是默認參數,接著是*args,最后是**kwargs。例如:?
def func(a, b, c=0, *args, **kwargs):?print(f"a={a}, b={b}, c={c}")?print("args:", args)?print("kwargs:", kwargs)?
?
func(1, 2, 3, 4, 5, name="test", age=10)?
# 輸出:?
# a=1, b=2, c=3?
# args: (4, 5)?
# kwargs: {'name': 'test', 'age': 10}?
三、函數的返回值?
函數的返回值是函數執行完成后給出的結果,通過return語句實現。?
用return返回結果,函數執行到return后停止,后續的代碼不會執行。?
def check_number(num):?if num > 0:?return "正數"?print("該數不是正數")?
?
print(check_number(5)) # 輸出:正數?
print(check_number(-3)) # 輸出:該數不是正數 然后輸出None?
當num為 5 時,函數執行到return "正數"就停止,不會執行后面的打印語句;當num為 - 3 時,不滿足if條件,會執行打印語句,然后函數默認返回None。?
可返回多個值,以元組形式接收,也可分別接收。?
def get_name_and_age():?return "Alice", 20?
?
# 以元組形式接收?
info = get_name_and_age()?
print(info) # 輸出:('Alice', 20)?
?
# 分別接收?
name, age = get_name_and_age()?
print(name, age) # 輸出:Alice 20?
四、匿名函數?
用lambda創建,語法:lambda 參數: 表達式,適合實現簡單的功能,返回值是表達式的結果。?
add = lambda a, b: a + b?
print(add(3, 5)) # 輸出:8?
?
# 結合內置函數使用?
numbers = [(1, 3), (4, 1), (2, 5)]?
# 按元組中第二個元素排序?
numbers.sort(key=lambda x: x[1])?
print(numbers) # 輸出:[(4, 1), (1, 3), (2, 5)]?
?
匿名函數通常與map、filter、sorted等內置函數配合使用,使代碼更簡潔。?
五、函數的作用域?
函數的作用域指的是變量可被訪問的范圍,分為局部作用域和全局作用域。?
- 局部作用域:在函數內部定義的變量,只能在函數內部訪問,稱為局部變量。?
def func():?local_var = 10?print(local_var)?
?
func() # 輸出:10?
print(local_var) # 報錯,local_var未定義?
local_var是在func函數內部定義的局部變量,在函數外部無法訪問。?
- 全局作用域:在函數外部定義的變量,可在函數內部訪問(但修改需要用global關鍵字聲明),稱為全局變量。?
global_var = 20?
?
def func1():?print(global_var) # 訪問全局變量?
?
def func2():?global global_var # 聲明修改全局變量?global_var = 30?
?
func1() # 輸出:20?
func2()?
print(global_var) # 輸出:30?
global_var是全局變量,func1函數內部可以直接訪問;func2函數要修改全局變量,需要用global關鍵字聲明,否則會被認為是定義了一個局部變量。?
- 非局部作用域:在嵌套函數中,內部函數訪問外部函數的變量(非全局變量),稱為非局部變量,若要修改需用nonlocal關鍵字聲明。?
def outer_func():?outer_var = 100?def inner_func():?nonlocal outer_var # 聲明修改非局部變量?outer_var = 200?print("inner:", outer_var)?inner_func()?print("outer:", outer_var)?
?
outer_func()?
# 輸出:?
# inner: 200?
# outer: 200?
outer_var是外部函數outer_func定義的變量,內部函數inner_func要修改它,需用nonlocal關鍵字聲明,修改后外部函數中該變量的值也會改變。
六、嵌套函數?
在一個函數內部定義另一個函數,內部的函數稱為嵌套函數。嵌套函數可以訪問外部函數的變量(若要修改需用nonlocal關鍵字)。?
def outer_func(x):?def inner_func(y):?return x + y?return inner_func?
?
add5 = outer_func(5)?
print(add5(3)) # 輸出:8?
inner_func是outer_func的嵌套函數,它可以訪問outer_func的參數x。outer_func(5)返回inner_func函數,然后add5(3)調用該函數,計算 5+3 的結果。?
七、閉包?
閉包是指嵌套函數中,內部函數引用了外部函數的變量,并且外部函數返回了內部函數。閉包可以保留外部函數的變量狀態。?
def make_multiplier(factor):?def multiplier(number):?return number * factor?return multiplier?
?
times3 = make_multiplier(3)?
times5 = make_multiplier(5)?
?
print(times3(10)) # 輸出:30?
print(times5(10)) # 輸出:50?
在這個例子中,multiplier是內部函數,它引用了外部函數make_multiplier的變量factor,并且make_multiplier返回了multiplier,所以形成了閉包。times3和times5分別保留了factor為 3 和 5 的狀態,因此調用時會得到不同的結果。?
八、遞歸函數?
遞歸函數是指在函數內部調用自身的函數,常用于解決具有遞歸性質的問題,即問題可以分解為與原問題相似但規模更小的子問題。使用遞歸函數需要注意設置終止條件,避免無限遞歸。?
遞歸函數的應用場景?
- 數學問題:如階乘計算、斐波那契數列、漢諾塔問題等。?
- 數據結構遍歷:如樹的深度優先遍歷、鏈表的某些操作等。?
- 算法實現:如快速排序、歸并排序等排序算法的遞歸實現。?
實例?:計算階乘?
def factorial(n):?if n == 1: # 終止條件?return 1?return n * factorial(n - 1)?
?
print(factorial(5)) # 輸出:120,5! = 5*4*3*2*1 = 120?
當n為 1 時,函數返回 1,否則返回n乘以n-1的階乘,通過不斷調用自身來計算結果。?
計算斐波那契數列(第 n 項)?
def fibonacci(n):?if n <= 1: # 終止條件?return n?return fibonacci(n - 1) + fibonacci(n - 2)?
?
print(fibonacci(6)) # 輸出:8,斐波那契數列前幾項:0,1,1,2,3,5,8...第6項是8?
總結
函數通過模塊化設計降低了代碼冗余,其豐富的參數類型與高級特性(如閉包、遞歸)使其能適應從簡單計算到復雜邏輯的多種場景。掌握函數的命名規范、參數傳遞機制、作用域規則及高級特性的應用,是編寫高效、可讀、可維護 Python 代碼的基礎。在實際開發中,需根據具體需求選擇合適的函數形式與參數類型,充分發揮函數的封裝與復用價值。