解密閉包:函數如何記住外部變量

🧠 什么是閉包?

閉包是一個函數對象,它不僅記住它的代碼邏輯,還記住了定義它時的自由變量(即非全局也非局部,但被內部函數引用的變量)。即使外部函數已經執行完畢,這些自由變量的值仍然保存在內存中,可以通過閉包訪問和使用。

簡單來說:

  • 當一個嵌套的函數引用了其外部函數中的變量,并且這個嵌套函數可以在其外部函數之外被調用時,就形成了一個閉包。


? 閉包的基本結構

def?outer_function(x):def?inner_function(y):return?x?+?yreturn?inner_function
closure?=?outer_function(10)
print(closure(5))??#?輸出:?15

在這個例子中,inner_functionouter_function 的內部函數,并且引用了 outer_function 的參數 x。當 outer_function 返回 inner_function 時,盡管 outer_function 已經執行結束,但是 inner_function 依然保留了對外部變量 x 的引用,這就形成了一個閉包。


? 閉包的工作原理

閉包允許你在一個函數內創建并返回另一個函數,而后者能夠“記住”前者內部的變量狀態。這種特性對于需要保持某些狀態的應用場景特別有用,比如計數器等。

示例:簡單的計數器

def?make_counter():count?=?0def?counter():nonlocal?count??#?使用?nonlocal?聲明?count?是外部函數中的變量count?+=?1return?countreturn?counter
counter?=?make_counter()
print(counter())??#?輸出:?1
print(counter())??#?輸出:?2
print(counter())??#?輸出:?3

在這個例子中,make_counter 函數返回了一個閉包 counter,它可以不斷增加并返回一個計數值。注意這里使用了 nonlocal 關鍵字來表明我們要修改的是外部函數中的 count 變量。


? 為什么使用閉包?

  1. 封裝:閉包可以幫助我們封裝一些數據,避免全局變量的污染。

  2. 狀態保持:通過閉包,我們可以輕松地實現帶有狀態的函數。

  3. 減少命名沖突:由于閉包內部使用的變量對外部不可見,因此減少了命名沖突的風險。


? 閉包與裝飾器

閉包的一個常見應用場景就是作為裝飾器的基礎。裝飾器本質上也是一個閉包,它接受一個函數作為輸入,并返回一個新的函數,通常用于在不改變原函數的情況下添加額外的功能。

示例:簡單的裝飾器

def?decorator(func):def?wrapper():print("Something?is?happening?before?the?function?is?called.")func()print("Something?is?happening?after?the?function?is?called.")return?wrapper
@decorator
def?say_hello():print("Hello!")
say_hello()

輸出:

Something is happening before the function is called.Hello!Something is happening after the function is called.

?? 注意事項

  1. 可變對象:如果閉包中引用的對象是可以變的(如列表),那么對這個對象的任何更改都會反映在閉包中。

  2. 性能問題:雖然閉包很強大,但在某些情況下可能會導致性能問題或增加程序復雜度,所以應謹慎使用。


📌 總結

  • 閉包是由函數及其相關引用環境組合而成的實體。

  • 它允許函數“記住”并訪問其定義范圍內的變量,即使那個函數在其定義的作用域外被調用。

  • 閉包廣泛應用于各種編程模式中,如裝飾器、工廠函數等。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86921.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86921.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86921.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

I2C協議詳解及STM32 HAL庫硬件I2C卡死問題分析

一、I2C協議詳解 1. I2C協議概述 Inter-Integrated Circuit (I2C) 是由 Philips 半導體(現 NXP 半導體)于 1980 年代設計的一種同步串行通信總線協議。該協議采用半雙工通信模式,支持多主從架構,專為短距離、低速率的芯片間通信…

HTTP協議-后端接收請求

起因就是不知道post這個請求體中這些格式有什么區別,后端又怎么去接收這些不同格式的內容 Get請求 get請求是比較簡單的一類 正常的直接用參數接收(不寫的話名字要匹配)或者RequestParam都可以接收,用對象綁定也可以 resultful…

HTML5 實現的圣誕主題網站源碼,使用了 HTML5 和 CSS3 技術,界面美觀、節日氛圍濃厚。

以下是一個 HTML5 實現的圣誕主題網站源碼,使用了 HTML5 和 CSS3 技術,界面美觀、節日氛圍濃厚。它包括: 圣誕樹動畫 🎄雪花飄落特效 ??圣誕祝福語 🎁響應式布局,適配移動端 你可以將代碼保存為 index.…

Spring Cloud Bus 和 Spring Cloud Stream

Spring Cloud Bus 和 Spring Cloud Stream 都是 Spring Cloud 生態中的消息通信組件,但它們的定位和使用場景有顯著區別: 1. Spring Cloud Bus 核心定位:分布式系統的消息廣播(配置刷新、事件傳播)。 典型場景&#x…

磁懸浮軸承位移信號的高精度估計:卡爾曼濾波算法深度解析

無需位移傳感器,濾波算法如何實現微米級精度? 磁懸浮軸承作為革命性的非接觸式支承技術,憑借無磨損、無需潤滑、高轉速等優勢,在飛輪儲能、高速電機、人工心臟泵和航空航天領域獲得了廣泛應用。其核心控制依賴于對轉子位移信號的高精度實時檢測,傳統電渦流傳感器雖能提供位…

DAY 43 預訓練模型

目錄 一、預訓練的概念 二、 經典的預訓練模型 2.1 CNN架構預訓練模型 2.2 Transformer類預訓練模型 2.3 自監督預訓練模型 三、常見的分類預訓練模型介紹 3.1 預訓練模型的發展史 3.2 預訓練模型的訓練策略 知識點回顧: 預訓練的概念常見的分類預訓練模型圖像…

Redis:事物

🌈 個人主頁:Zfox_ 🔥 系列專欄:Redis 🔥 什么是事務 Redis的事務和MySQL的事務概念上是類似的.都是把?系列操作綁定成?組.讓這?組能夠批量執?. 但是注意體會Redis的事務和MySQL事務的區別: 弱化的原?性:redi…

CppCon 2018 學習:An allocator is a handle to a heap Lessons learned from std::pmr

“An allocator is a handle to a heap — Lessons learned from std::pmr” 翻譯過來就是:“分配器(allocator)是對堆(heap)的一種句柄(handle)——從 std::pmr 中學到的經驗”。 基礎概念 分…

設備健康實時監測方法演進:從傳感網絡到AI決策樹的工業智能實踐

引言:當設備運維遇上AIoT革命 在工業4.0進程中,?毫秒級設備狀態捕獲能力正成為智能工廠的核心競爭力。傳統監測方法因數據滯后、診斷粗放被詬病,本文將深入探討三大前沿實時監測技術路徑,并揭秘中訊燭龍系統如何通過深度強化學習…

劍指offer53_二叉樹的深度

二叉樹的深度 輸入一棵二叉樹的根結點,求該樹的深度。 從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度為樹的深度。 數據范圍 樹中節點數量 [ 0 , 500 ] [0,500] [0,500]。 樣例 輸入&#…

探秘AI的秘密:leaked-system-prompts

揭秘:揭秘系統提示合集背后的秘密 在當今這個人工智能技術迅速發展的時代,了解和使用大型語言模型(LLM)已成為技術愛好者、開發者和研究人員的共同目標。而作為核心組成部分,系統提示(system prompts)的設計和應用直接影響了LLM的表現和功能。今天, 我們將為大家揭示一…

Gaming Mode四大功能(VRR、QMS、QFT、ALLM)

HDMI 2.1定義的Gaming Mode四大功能(VRR、QMS、QFT、ALLM)通過協同優化幀傳輸、刷新率同步與延遲控制,顯著提升了游戲和影音的流暢性與響應速度。以下是這些功能的詳細解析及其應用價值: 🔄 1. 可變刷新率(…

數據庫總結(關系代數-函數依賴-范式)

以下是關系代數中基本操作的詳細說明: 并(Union) 關系R和S的并操作表示為R ∪ S,要求R和S具有相同的屬性集(并相容性)。結果包含所有屬于R或S的元組,自動去除重復項。 示例: R …

react經驗:在nextjs中使用motion組件

什么是motion組件? 一種動畫組件 motion組件文檔 在nextjs中的應用步驟 1.安裝motion npm i framer-motion2.在next.config.js中配置轉義 export default {transpilePackages: [framer-motion] }3.開始應用 **注意要點:**在服務端渲染不可直接用&am…

怎樣大語言模型 遵守規則

如何讓應用中的提示工程更能適應未來變化 目錄 如何讓應用中的提示工程更能適應未來變化怎樣大語言模型 遵守規則提示詞 很有效:Memorize these rules提示可分為穩定組件和易變組件怎樣大語言模型 遵守規則 實驗背景:讓大語言模型可靠地遵守規則很難,尤其是規則數量增多時。…

如何通過SSL證書配置防止源站IP泄露 - 全面防護指南

問題背景:SSL證書如何導致源站IP泄露 近期多位站長反饋,即使已部署高防CDN并做好源站IP保密工作,服務器仍頻繁遭受DDoS攻擊。經深入排查,發現問題根源在于SSL證書。當前網絡環境中存在大量爬蟲工具24小時不間斷掃描全網IP地址&am…

醫院信息化發展要經過哪幾個階段

目前,幾乎所有的醫院都離不開信息技術的建設和支持。沒有信息技術,醫院的業務可能無法繼續。醫院信息化的發展主要經歷三個階段,即醫院管理信息化階段、臨床管理信息化階段和醫療智能化階段。從基礎設施的角度來看,每個階段都有不…

【Vscode】Vscode切換成中文語言

安裝中文語言包 啟動 VSCode。按下Ctrl Shift X(或者點擊左側邊欄的擴展圖標),打開擴展面板。在搜索框中輸入Chinese (Simplified),在搜索結果里找到Chinese (Simplified) Language Pack for Visual Studio Code并點擊安裝按鈕…

【百日精通JAVA | 數據結構篇】 一文了解泛型體系

一、初識泛型 在推出泛型以前,程序員可以創建一個元素類型Object的集合,該集合能夠存儲任意的數據類型對象,而在使用該集合的過程中,需要明確知道存儲每個元素的類型,否則容易引發ClassCastException異常。 泛型是JD…

賦能 Java 工程,飛算科技重新定義智能開發

在數字經濟蓬勃發展的當下,軟件開發行業正經歷著前所未有的變革。飛算科技作為一家自主創新型的數字科技公司,始終以互聯網科技、大數據、人工智能等前沿技術為根基。憑借團隊在相關領域多年積累的深厚實踐經驗,公司深度融合技術與應用&#…