在Python中,函數嵌套是指在一個函數(我們稱之爲“外部函數”)的內部定義另一個函數(我們稱之爲“內部函數”)。這種結構允許我們在函數內部創建更復雜的邏輯,或者實現一些需要“隱藏”的功能。
一、如何定義函數嵌套?¶
定義函數嵌套非常簡單,只需在外部函數的代碼塊中,使用def關鍵字定義內部函數即可。例如:
def outer_function(): # 外部函數
print("這是外部函數 outer_function")
def inner_function(): # 內部函數,定義在外部函數內部
print("這是內部函數 inner_function")
# 現在可以在外部函數中使用內部函數了
inner_function() # 直接調用內部函數
二、如何調用嵌套的函數?¶
內部函數的作用域僅限於外部函數內部,因此直接在外部函數外部調用內部函數會報錯。調用方式主要有兩種:
1. 在外部函數內部直接調用內部函數¶
最直接的方式是在外部函數中直接使用內部函數名,像調用普通函數一樣調用它。例如上面的例子:
outer_function() # 調用外部函數
執行結果:
這是外部函數 outer_function
這是內部函數 inner_function
2. 通過外部函數返回內部函數¶
如果需要在外部函數外部使用內部函數,可以讓外部函數返回內部函數對象,然後通過返回的對象調用內部函數。例如:
def outer_function():
def inner_function():
print("這是內部函數 inner_function")
return inner_function # 返回內部函數對象
# 調用外部函數,得到內部函數對象
inner = outer_function()
inner() # 通過返回的對象調用內部函數
執行結果:
這是內部函數 inner_function
三、內部函數與外部函數的變量作用域¶
內部函數可以訪問外部函數的變量,但外部函數無法直接訪問內部函數的變量。這種“作用域”規則是函數嵌套的核心特性之一:
1. 內部函數訪問外部函數的變量¶
內部函數可以直接使用外部函數的參數或局部變量。例如:
def outer_function(x):
def inner_function():
print("外部函數的參數 x 值爲:", x) # 內部函數訪問外部函數的 x
return inner_function
f = outer_function(100) # 外部函數傳入參數 100
f() # 調用內部函數,輸出外部函數的 x
執行結果:
外部函數的參數 x 值爲: 100
2. 外部函數無法訪問內部函數的變量¶
外部函數不能直接訪問內部函數的局部變量,因爲內部函數的作用域僅限於自身。例如:
def outer_function():
def inner_function():
y = 200 # 內部函數的局部變量
inner_function()
print(y) # 錯誤!外部函數無法訪問內部函數的 y
outer_function()
執行結果會報錯:NameError: name 'y' is not defined
四、函數嵌套的常見用途¶
函數嵌套是Python中許多高級特性的基礎,例如:
1. 實現閉包(Closure)¶
閉包允許內部函數“記住”外部函數的狀態(如變量值),即使外部函數已經執行完畢。例如:
def outer_function(x):
def inner_function():
print("x 的值是:", x) # 內部函數記住 x 的值
return inner_function
f = outer_function(5) # 外部函數執行完畢,但 x=5 被“記住”
f() # 輸出:x 的值是:5
2. 實現裝飾器(Decorator)¶
裝飾器是函數嵌套的經典應用,用於給函數添加額外功能(如計時、日誌記錄)而不修改原函數代碼。例如:
def timer_decorator(func):
def wrapper():
print("開始計時...")
func() # 調用原函數
print("計時結束")
return wrapper
@timer_decorator # 等價於:func = timer_decorator(func)
def func():
print("我是原函數")
func() # 調用裝飾後的函數
執行結果:
開始計時...
我是原函數
計時結束
五、總結¶
函數嵌套是Python中強大的特性,通過在外部函數內部定義內部函數,可以實現:
- 代碼的模塊化和封裝(隱藏內部函數細節);
- 保存臨時狀態(閉包);
- 實現裝飾器等高級功能。
初學者可以從簡單的嵌套調用和變量作用域開始練習,逐步理解其在實際開發中的應用。
練習:嘗試寫一個函數嵌套的例子,讓內部函數訪問外部函數的多個變量,並返回內部函數,最後調用它。