Python - 闭包:初學者指南
你好,有抱负的Python程序員!今天,我們將進入一個令人興奮的旅程,探索闭包的世界。如果你從未聽過這個術語,也別擔心 - 當你完成這篇教程時,你不但會理解什么是闭包,還能在自己的代碼中創建和使用它們。那麼,讓我們開始吧!
什麼是闭包?
想象一下,你有一個神奇的盒子,即使關上它也能記住事情。這就是编程中闭包的基本概念!在Python中,闭包是一個函數對象,它記住包圍範圍內的值,即使它們不在內存中。
聽起來很困惑嗎?讓我們來解析一下:
- 它是另一個函數內部的函數。
- 它可以訪問外部函數的變量。
- 即使外部函數已經執行完畢,它也會記住這些變量。
將其視為創建一個小包的功能,攜帶著自己的私有數據。很酷,對吧?
嵌套函數
在我們深入探討闭包之前,讓我們先談談嵌套函數。這些只是定義在其他函數內部的函數。這裡有一個簡單的例子:
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
result = outer_function(10)
print(result(5)) # 輸出:15
在這個例子中,inner_function
嵌套在outer_function
內部。內部函數可以訪問外部函數的x
參數。這是理解闭包的一個關鍵概念。
變量範圍
要真正掌握闭包,我們需要理解Python中的變量範圍。有三種類型的範圍:
- 局部範圍:在函數內定義的變量
- 包圍範圍:嵌套函數的外部函數中的變量
- 全局範圍:在模塊頂層定義的變量
這裡有一個例子來說明:
x = "我是全局的!" # 全局範圍
def outer():
y = "我來自outer!" # 包圍範圍
def inner():
z = "我是本地的!" # 局部範圍
print(x, y, z)
inner()
outer()
當你運行這段代碼時,你將看到打印出所有三個變量。inner
函數可以訪問三個範圍中的變量!
創建一個闭包
現在我們已經理解了嵌套函數和變量範圍,讓我們來創建一個闭包。當一個嵌套函數在其包圍範圍內引用一個值時,就會發生閉包。這裡有一個例子:
def multiply_by(n):
def multiplier(x):
return x * n
return multiplier
times_two = multiply_by(2)
times_three = multiply_by(3)
print(times_two(5)) # 輸出:10
print(times_three(5)) # 輸出:15
在這個例子中,multiply_by
是我們的外部函數,multiplier
是我們的內部函數。當我們返回multiplier
時,魔法就發生了 - 它記住n
的值,即使multiply_by
已經執行完畢。這就是一個閉包!
讓我們逐步分解:
- 我們定義了帶有參數
n
的multiply_by
。 - 在
multiply_by
內部,我們定義了帶有參數x
的multiplier
。 -
multiplier
使用其自己的參數x
和外部函數的n
。 - 我們從
multiply_by
返回multiplier
。 - 當我們調用
multiply_by(2)
時,它返回一個總是將其輸入乘以2的函數。 - 同樣,
multiply_by(3)
返回一個總是將其輸入乘以3的函數。
這就是閉包的力量 - 它們可以即時創建專門的函數!
nonlocal
關鍵字
有時,你可能想在內部函數中修改包圍範圍內的變量。Python為此提供了nonlocal
關鍵字。這裡有一個例子:
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
my_counter = counter()
print(my_counter()) # 輸出:1
print(my_counter()) # 輸出:2
print(my_counter()) # 輸出:3
在這個例子中,increment
是一個閉包,它記住並修改其包圍範圍內的count
變量。nonlocal
關鍵字告訴Python count
不是一個局部變量,而是包圍範圍內的變量。
闭包的實際應用
閉包不僅是一個很酷的技巧 - 它們還有實際應用!以下是一些:
- 數據隱藏和封裝
- 創建函數工廠
- 實現裝飾器
讓我們看看一個現實世界的例子。想象一下你正在為一家在線商店創建一個折扣系統:
def create_price_adjuster(discount):
def adjust_price(price):
return price * (1 - discount)
return adjust_price
black_friday_sale = create_price_adjuster(0.2) # 20% off
cyber_monday_sale = create_price_adjuster(0.15) # 15% off
original_price = 100
print(f"Black Friday price: ${black_friday_sale(original_price)}")
print(f"Cyber Monday price: ${cyber_monday_sale(original_price)}")
這段代碼為不同的銷售活動創建了不同的定價函數,所有這些都使用同一個基礎函數。這就是閉包的力量!
總結
恭喜你!你剛剛學習了Python的一個更先進的功能。讓我們回顧一下我們所涉及的內容:
概念 | 描述 |
---|---|
闭包 | 記住包圍範圍內值的函數 |
嵌套函數 | 定義在另一個函數內部的函數 |
變量範圍 | 變量的可見性(局部,包圍,全局) |
nonlocal |
修改包圍範圍內變量的關鍵字 |
請記住,像任何強大的工具一樣,閉包應該謹慎使用。它們適合某些任務,但過度使用它們可能會使你的代碼難以理解。練習,實驗,你很快就會像Python專家一樣運用閉包!
編程愉快,並且記住 - 在Python中,就像在生活中一樣,重要的是內部(函數)!
Credits: Image by storyset