python閉包 - 理解與應用

Binzichen發表於2024-04-26

閉包定義

閉包是指在一個函式內部定義的函式,並且這個內部函式可以訪問外部函式的區域性變數。當外部函式執行完畢後,內部函式仍然可以訪問外部函式的區域性變數,這種函式就稱為閉包。

在Python中,閉包通常用來儲存一些狀態資訊,可以在外部函式執行完畢後繼續使用這些狀態資訊。閉包可以幫助我們實現一些特定功能,比如儲存函式的狀態,實現裝飾器等。

示例

def outer_func():
    x = 10
    
    def inner_func():
        print(x)
    
    return inner_func

closure = outer_func()
closure()  # 輸出:10

在這個例子中,inner_func是一個閉包,它可以訪問外部函式outer_func的區域性變數x。當呼叫closure()時,內部函式inner_func仍然可以訪問並列印外部函式的區域性變數x的值。

閉包實際應用

儲存狀態資訊

儲存狀態資訊:閉包可以用來儲存一些狀態資訊,這些資訊可以在外部函式執行完畢後繼續使用。例如,可以使用閉包來記錄函式呼叫的次數或者實現計數器功能。

def counter():
    count = 0
    
    def inner_counter():
        nonlocal count
        count += 1
        return count
    
    return inner_counter

c = counter()
print(c())  # 輸出:1
print(c())  # 輸出:2

實現裝飾器

閉包可以用來實現裝飾器,即在不修改原函式程式碼的情況下,為函式新增額外的功能。

def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    
    return wrapper

@my_decorator
def say_hello():
    print("Hello")

say_hello()

在這個例子中,my_decorator是一個閉包,它接受一個函式作為引數,並返回一個新的函式wrapper,在wrapper中新增了額外的功能。透過裝飾器語法@my_decorator,我們可以在say_hello函式呼叫前後列印額外的資訊。

回撥函式

閉包經常用作回撥函式,用於非同步程式設計或事件處理。例如,當某個事件發生時,可以呼叫一個閉包函式來處理該事件。

def event_handler(callback):
    def inner_event_handler(event):
        print("Event:", event)
        callback(event)
    
    return inner_event_handler

def on_event(event):
    print("Handling event:", event)

handler = event_handler(on_event)
handler("click")  # 輸出:Event: click Handling event: click

快取函式

閉包可以用來實現函式的結果快取,以提高效能。例如,可以將函式的輸入引數和對應的輸出結果儲存在閉包中,下次呼叫函式時可以直接返回快取的結果。

def memoize(func):
    cache = {}
    
    def memoized_func(n):
        if n not in cache:
            cache[n] = func(n)
        return cache[n]
    
    return memoized_func

@memoize
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(5))  # 輸出:5

實現私有變數

閉包可以用來模擬私有變數,即外部函式的區域性變數對外部不可見,但內部函式仍然可以訪問和修改這些變數。

def private_variable():
    secret = "I am a secret"
    
    def get_secret():
        return secret
    
    def set_secret(new_secret):
        nonlocal secret
        secret = new_secret
    
    return get_secret, set_secret

get_secret, set_secret = private_variable()
print(get_secret())  # 輸出:I am a secret
set_secret("New secret")
print(get_secret())  # 輸出:New secret

這些例子展示了閉包的多種用途,包括儲存狀態資訊、實現裝飾器、回撥函式、快取函式和模擬私有變數等。透過閉包,我們可以實現更加靈活和功能性強大的程式碼結構。

相關文章