Python 閉包詳解:從變量作用域到實戰案例

一、變量作用域基礎

在 Python 中,變量根據作用范圍可分為三類:

  1. 全局變量:定義在函數外部的變量,作用范圍是整個程序。如果在函數內部需要修改全局變量,必須使用global關鍵字聲明。

  2. 局部變量:定義在函數內部的變量,僅在該函數內部有效。需要注意的是,這是在不存在內部函數的前提下。

  3. 非局部變量:從內部函數的角度來看,外部函數中定義的變量稱為非局部變量。當內部函數需要修改非局部變量時,必須使用nonlocal關鍵字進行聲明。

二、閉包的概念與構成條件

閉包是 Python 中一個重要的概念,它滿足以下三個條件:

  • 外部函數嵌套內部函數
  • 內部函數被返回
  • 內部函數訪問外部函數的非局部變量

閉包的優缺點

優點

  • 可以避免全局變量被污染
  • 是實現裝飾器的基礎

缺點

  • 外部函數的非局部變量會一直被內部函數引用,導致變量長時間得不到回收,可能造成內存泄漏
  • 內存泄漏與內存溢出不同:內存泄漏是指數據無法回收,無法釋放內存;內存溢出則是指空間不夠用,數據溢出

注意:閉包雖有其用途,但應遵循 "能不用就不用" 的原則

三、閉包實戰案例

案例 1:帶限制的年齡增長函數

def outter():a = 10  # 局部變量age = 1  # 非局部變量def inner(n):nonlocal age  # 聲明使用外部函數的非局部變量ageif age + n < 120:age += nreturn agereturn '數據不合法'return inner  # 返回內部函數# 調用方式:先獲取內部函數,再調用內部函數
print(outter()(8))  # 輸出:9

在這個案例中:

  • outter()是外部函數,inner(n)是內部函數
  • age是外部函數的變量,對內部函數來說是是非局部變量
  • 內部函數inner(n)訪問并修改了非局部變量age
  • 外部函數返回了內部函數,形成了閉包
  • 該閉包實現了年齡增長的功能,并限制年齡不超過 120

案例 2:實現計數器功能

# 實現計數器
def outter1():a = 1  # 初始值def inner1(n):nonlocal a  # 聲明使用外部函數的非局部變量aa += n  # 累加n值return areturn inner1  # 返回內部函數,不要加括號# 使用計數器
o = outter1()  # 獲取內部函數
print(o(1))  # 輸出:2
print(o(1))  # 輸出:3
print(o(1))  # 輸出:4
print(o(1))  # 輸出:5
print(o(1))  # 輸出:6

這個計數器案例很好地展示了閉包的特性:

  • 變量a被保存在閉包環境中,不會隨著外部函數的執行結束而銷毀
  • 每次調用內部函數,都會基于上一次的結果進行計算
  • 不需要使用全局變量就能實現狀態的保持,避免了全局變量污染

四、總結

????????閉包是 Python 中一個強大的特性,它通過外部函數嵌套內部函數,并讓內部函數引用外部函數的變量,同時返回內部函數,實現了數據的封裝和狀態的保持。

????????合理使用閉包可以提高代碼的封裝性和安全性,但也要注意其可能帶來的內存問題。在實際開發中,應根據具體場景權衡使用,遵循 "必要時才使用" 的原則。

????????掌握閉包不僅有助于理解 Python 的變量作用域,也是學習裝飾器等高級特性的基礎。希望通過本文的講解和案例,能幫助大家更好地理解和運用 Python 閉包。

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

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

相關文章

Docker 跨主機容器之間的通信macvlan

默認一個物理網卡&#xff0c;只有一個物理mac地址&#xff0c;虛擬多個mac地址 缺點&#xff1a;每次需要手動配置ip地址&#xff0c;容易ip地址沖突。類似于保存到execl表格里面。 兩臺物理機&#xff1a; docker-01和docker-02 創建macvlan網絡 [rootdocker-01 ~]# docker n…

android 換膚框架詳解1-換膚邏輯基本

android 換膚框架詳解1-換膚邏輯基本-CSDN博客 android 換膚框架詳解2-LayoutInflater源碼解析-CSDN博客 android 換膚框架詳解3-自動換膚原理梳理-CSDN博客 換膚框架流程 1&#xff0c;通過AssetManager獲取換膚的資源文件 2&#xff0c;通過原文件中的resId獲取到res名稱…

NEON性能優化總結

轉自 NEON優化&#xff1a;性能優化經驗總結-CSDN博客 NEON優化&#xff1a;性能優化經驗總結 1. 什么是 NEON Arm Adv SIMD 歷史 2. 寄存器 3. NEON 命名方式 4. 優化技巧 5. 優化 NEON 代碼(Armv7-A內容&#xff0c;但區別不大) 5.1 優化 NEON 匯編代碼 …

計算機網絡摘星題庫800題筆記 第2章 物理層

第2章 物理層2.1 物理層概述題組闖關1.采用以下哪種設備&#xff0c;可以使數字信號傳輸得更遠 ( )。 A. 放大器 B. 中繼器 C. 網橋 D. 路由器1.【參考答案】B 【解析】選項 A 放大器只是單純地放大信號、抑制噪音和干擾。選項 B 中繼器是把一根線纜中的電或者光信號傳遞給另一…

導入文件到iPhone實現

我們有時候開發需要加載一些自己的文件&#xff0c;這個時候就需要導入文件到iPhone等設備。在info里面open as source code&#xff0c;加入如下配置&#xff1a;<!-- 開啟 iTunes / Finder 文件共享 --><key>UIFileSharingEnabled</key><true/>或者o…

Ubuntu Server系統安裝磁盤分區方案

最近打算把家里的舊電腦利用起來&#xff0c;裝上Ubuntu Server 24.04.3 LTS作為一個家用NAS服務器&#xff0c;但是給舊電腦安裝系統時遇到了一些問題&#xff0c;遂記錄下來 GPT分區與MBR分區 GPT 指的是 GUID Partition Table&#xff08;全局唯一標識分區表&#xff09;&am…

1小時 MySQL 數據庫基礎速通

目錄 一、MySQL安裝配置 1、下載mysql 2、下載mysql-shell 二、MySQL基本概念 1. 數據庫&#xff08;Database&#xff09; 2. 表&#xff08;Table&#xff09; 3. 數據類型&#xff08;Data Type&#xff09; 4. 主鍵&#xff08;Primary Key&#xff09; 5. 索引&am…

HTTP應用層協議-長連接

HTTP應用層協議-長連接 關于 connection 報頭 HTTP 中的 Connection 字段是 HTTP 報文頭的一部分&#xff0c;它主要用于控制和管理客戶端與服務器之間的連接狀態 核心作用 ? 管理持久連接&#xff1a;Connection 字段還用于管理持久連接&#xff08;也稱為長連接&#xff09;…

2020/12 JLPT聽力原文 問題一 4番

4番&#xff1a;ホテルの受付で女の人と男の人が話しています。女の人はどこでパソコンを使いますか。女&#xff1a;すみません、パソコンの貸出ってできますか。部屋で仕事をしたいんですけど。 男&#xff1a;申し訳ございません。貸出はしていないんですが、二階にビジネス…

《在 Spring Boot 中安全使用 Qwen API-KEY:環境變量替代明文配置的最佳實踐》

《在 Spring Boot 中安全使用 Qwen API-KEY&#xff1a;環境變量替代明文配置的最佳實踐》 想要的效果其實就是 把 Qwen API-KEY 放到系統環境變量中&#xff0c;然后在 application.yml 里通過占位符讀取&#xff0c;而不寫明文。 這樣即便 application.yml 被提交到 Git&…

Nginx 反向代理與負載均衡架構

一、反向代理基礎 實驗目的&#xff1a;通過 Nginx 反向代理&#xff0c;將客戶端請求按類型&#xff08;靜態頁面 / 動態 PHP 頁面&#xff09;轉發到不同的后端服務器&#xff08;RS1 處理靜態資源&#xff0c;RS2 處理動態請求&#xff09;&#xff0c;實現 “客戶端只與代…

【Mybatis入門】配置Mybatis(IDEA)

Mybatis和JDBC一樣&#xff0c;是連接數據庫的工具。它是一款優秀的持久層框架&#xff0c;主要用于 Java 語言中簡化數據庫操作&#xff0c;實現對象與數據庫表之間的映射。Mybatis相比于JDBC的優勢Mybatis消除了傳統 JDBC 代碼中繁瑣的手動處理、參數設置、結果集解析等重復工…

多路轉接之epoll 【接口】【細節問題】【LT與ET模式】【Reactor】

目錄 一.接口 1.1epoll_creaet 1.2epoll_ctl 1.3epoll_wait 二.細節問題 2.1 工作原理 2.2 epoll的demo 2.3 epoll的優點 三. LT 與 ET模式 理解ET 四. reactor 一.接口 1.1epoll_creaet 注意返回值是一個文件描述符 創建一個epoll模型 1.2epoll_ctl 返回值&…

滲透測試現已成為 CISO 戰略的核心

隨著數字供應鏈的擴展以及生成式人工智能在關鍵系統中的嵌入&#xff0c;安全領導者正在重新思考其網絡安全策略。Emerald Research 最近對 225 位安全領導者進行的一項調查發現&#xff0c;68% 的人擔心第三方軟件和組件帶來的風險。雖然大多數受訪者表示他們正在滿足監管要求…

音視頻學習(五十三):音頻重采樣

概述 音頻重采樣&#xff08;sample rate conversion, SRC&#xff09;是把采樣率從 Fs_in 變換為 Fs_out 的過程。常見場景有格式轉換&#xff08;44.1→48 kHz&#xff09;、采樣率匹配&#xff08;播放鏈路統一采樣率&#xff09;、以及通信中語音采樣率升降&#xff08;8 k…

【C#】正則表達式

一、核心優勢&#xff1a;用一小段規則搞定大量復雜的字符串匹配&#xff0c;查找和替換&#xff0c;并且可移植可復用。使用正則表達式的好處&#xff1a;1. 強大且靈活&#xff1a;可以一次性匹配非常復雜的規則&#xff0c;比如驗證郵箱、提取特定的格式日志、解析URL&#…

【[特殊字符][特殊字符] 協變與逆變:用“動物收容所”講清楚 PHP 類型的“靈活繼承”】

你有沒有遇到過這樣的問題&#xff1a;“為什么子類方法可以返回 Cat&#xff0c;而父類只寫了返回 Animal&#xff1f;” “為什么參數反而能從 CatFood 變成更寬泛的 Food&#xff1f;”這些看似“違反直覺”的設計&#xff0c;其實背后有一個優雅的編程概念&#xff1a;協變…

cesium/resium 修改子模型材質

我是 www.v2ex.com/t/1151549 的作者&#xff0c;在csdn這邊補全一些更多的信息 相關工具 主項目插件版本&#xff1a; "cesium": "^1.131.0",、"resium": "^1.19.0-beta.1"、"three": "^0.178.0"、"react…

nvm install 14.21.3 時npm 無法下載和識別

錯誤&#xff1a;C:\Users\H3C>nvm install 14.21.3 Downloading node.js version 14.21.3 (64-bit)... Complete Downloading npm... Creating C:\Users\H3C\AppData\Local\Temp\nvm-install-939491942\temp Downloading npm version 6.14.18... Error while downloading h…

【網絡運維】Linux:LNMP 項目實踐

LNMP 項目實踐 簡介&#xff1a;什么是 LAMP/LNMP LAMP&#xff1a;LinuxApacheMysql/MariadbPHP/Python/Perl。 LNMP&#xff1a;LinuxNginxMysql/MariadbPHP/Python/Perl。 Linux&#xff1a;操作系統&#xff0c;提供程序運行基礎。Apache/Nginx&#xff1a;Web 服務器&…