函數嵌套:Python中如何在函數里定義另一個函數?

在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中強大的特性,通過在外部函數內部定義內部函數,可以實現:
- 代碼的模塊化和封裝(隱藏內部函數細節);
- 保存臨時狀態(閉包);
- 實現裝飾器等高級功能。

初學者可以從簡單的嵌套調用和變量作用域開始練習,逐步理解其在實際開發中的應用。

練習:嘗試寫一個函數嵌套的例子,讓內部函數訪問外部函數的多個變量,並返回內部函數,最後調用它。

小夜