首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python 閉包 完整指南:概念、計數器、裝飾器、非區域變數 nonlocal

     編輯:更多程式設計知識

閉包 = 函數 + 其捕獲的自由變數環境。Python 2 需用可變容器 (列表) 模擬非區域賦值,Python 3 引入 nonlocal 關鍵字直接支援。本文詳細解析閉包機制與三大應用模式。

基本範例:配置化函數工廠


def make_adder(addend):
    def adder(augend):
        return augend + addend
    return adder

p = make_adder(23)
q = make_adder(44)
print(p(100))  # 123
print(q(100))  # 144

addend 被內部函數捕獲,形成閉包。每次呼叫 make_adder 產生新環境,互不干擾。

應用 1:狀態保持計數器

Python 2 (列表技巧)


def counter():
    count = [0]
    def inc():
        count[0] += 1
        return count[0]
    return inc

Python 3 (nonlocal)


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

應用 2:裝飾器即閉包


def makebold(fn):
    def wrapped():
        return "" + fn() + ""
    return wrapped

def makeitalic(fn):
    def wrapped():
        return "" + fn() + ""
    return wrapped

@makebold
@makeitalic
def hello():
    return "hello world"

print(hello())  # hello world

裝飾器本質是接受函數、回傳增強函數的閉包。

應用 3:延遲執行 / 回呼


def later(fn, *args, **kwargs):
    def thunk():
        return fn(*args, **kwargs)
    return thunk

task = later(print, "deferred")
task()  # 輸出: deferred

閉包 vs 類別

特性閉包類別
語法輕量、函數式結構化、物件導向
狀態捕獲外部變數實例屬性
多方法需回傳多函數或字典天然支援
繼承不支援支援

常見陷阱

  1. 迴圈中建立閉包捕獲迴圈變數:

funcs = []
for i in range(3):
    funcs.append(lambda: i)
print([f() for f in funcs])  # [2, 2, 2] 全捕獲同一 i
# 修正: lambda i=i: i 或 functools.partial
  1. 可變預設參數陷阱 (非閉包但相關):

def f(x, lst=[]):  # lst 只建立一次
    lst.append(x)
    return lst

閉包是函數式程式設計核心概念,善用能大幅簡化狀態管理程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved