【從零學習python 】31.深入理解Python中的高階函數和閉包

文章目錄

  • 高階函數
    • 定義一個變量指向函數
    • 高階函數
      • 函數做為另一個函數的參數
      • 函數作為另一個函數的返回值
    • 閉包
      • 函數嵌套
      • 什么是閉包
      • 修改外部變量的值
        • 原因分析
        • 解決方案
    • 進階案例

高階函數

在Python中,函數其實也是一種數據類型。

def test():return 'hello world'print(type(test))  # <class 'function'>

函數對應的數據類型是 function,可以把它當做是一種復雜的數據類型。

既然同樣都是一種數據類型,我們就可以把它當做數字或者字符串來處理。

定義一個變量指向函數

在Python中,我們還可以定義一個變量,讓它來指向一個函數,相當于給函數起了一個別名。

def test():return 'hello wrold'fun = test   # 定義了一個變量fun,讓它指向了 test 這個函數
print(fun())   # 使用fun()可以直接調用test這個函數print(id(fun))  # 1819677672040
print(id(test))  # 1819677672040

注意:在定義一個變量表示一個函數時,函數后面不能加括號!加括號表示的是調用這個函數。

def test():return 'hello world'result = test()   # 這種寫法是調用test函數,并把函數的返回值賦值給result變量
print(result())   # 這里會報錯  TypeError: 'str' object is not callablefun = test   # 這種寫法是給test函數起了一個別名,注意,這里的test后面不能加()
fun()        # 可以使用別名調用這個函數

高階函數

既然變量可以指向函數,函數的參數能接收變量,那么一個函數就可以接收另一個函數作為參數,同樣,我們還可以把一個函數當做另一個函數的返回值。這種函數的使用方式我們稱之為高階函數。

函數做為另一個函數的參數

def test(age, action):if age < 18:print('您還沒滿十八歲,請退出')action()   # 把參數action直接當做一個函數來調用def smoke():print('我已經年滿十八歲了,我想抽煙')my_action = smoke  # 定義一個變量my_action,讓它指向smoke函數
test(21, my_action)  # 將my_action傳給test函數作為它的參數test(21, smoke)  # 還可以不再定義一個新的變量,直接傳入函數名

函數作為另一個函數的返回值

def test():print('我是test函數里輸入的內容')def demo():print('我是demo里輸入的內容')return test  # test 函數作為demo函數的返回值result = demo()  # 我是demo里輸入的內容  調用 demo 函數,把demo函數的返回值賦值給 result
print(type(result)) # <class 'function'>  result 的類型是一個函數result() # 我是demo里輸入的內容    我是test函數里輸入的內容   既然result是一個函數,那么就可以直接使用() 調用這個函數demo()()  # 我是demo里輸入的內容    我是test函數里輸入的內容

閉包

函數只是一段可執行代碼,編譯后就“固化”了,每個函數在內存中只有一份實例,得到函數的入口點便可以執行函數了。函數還可以嵌套定義,即在一個函數內部可以定義另一個函數,有了嵌套函數這種結構,便會產生閉包問題。

函數嵌套

在函數里面還可以定義函數,可以嵌套多層,執行需要被調用。

def outer():print('outer----hello')def inner():  # inner這個函數是在outer函數內部定義的print('inner----hello')inner()  # inner函數只在outer函數內部可見outer()
# inner()  這里會報錯,在outer函數外部無法訪問到inner函數

什么是閉包

閉包是由函數及其相關的引用環境組合而成的實體(即:閉包=函數塊+引用環境)。

def outer(n):num = ndef inner():return num+1return innerprint(outer(3)())  # 4
print(outer(5)())  # 5

在這段程序中,函數 inner 是函數 outer 的內嵌函數,并且 inner 函數是outer函數的返回值。我們注意到一個問題:內嵌函數 inner 中引用到外層函數中的局部變量num,Python解釋器會這么處理這個問題呢?先讓我們來看看這段代碼的運行結果,當我們調用分別由不同的參數調用 outer 函數得到的函數時,得到的結果是隔離的(相互不影響),也就是說每次調用outer函數后都將生成并保存一個新的局部變量num,這里outer函數返回的就是閉包。如果在一個內部函數里,對在外部作用域(但不是在全局作用域)的變量進行引用,那么內部函數就被認為是閉包(closure)。

修改外部變量的值

閉包里默認不能修改外部變量。

def outer(n):num = ndef inner():num = num + 1return numreturn innerprint(outer(1)())

上述代碼運行時會報錯!

UnboundLocalError: local variable 'num' referenced before assignment

原因分析

在python里,只要看到了賦值語句,就會認為賦值語句的左邊是一個局部變量。num = num + 1 這段代碼里,num=的左邊,python解析器會認為我們要修改inner函數里num這個局部變量,而這個變量使用之前是未聲明的,所以會報錯。

解決方案

我們分析過,報錯的原因在于當我們在閉包內修改外部變量時,會被python解析器誤會為內部函數的局部變量。所以,解決方案就在于,我們需要想辦法,讓解析器知道我們不是要修改局部變量,而是要修改外部變量。

解決方法:使用 nonlocal 關鍵字

def outer(n):num = ndef inner():nonlocal num  # 修改前使用nonlocal關鍵字對 num 變量進行說明num = num + 1return numreturn innerprint(outer(2)())

進階案例

【Python】Python 實現猜單詞游戲——挑戰你的智力和運氣!

【python】Python tkinter庫實現重量單位轉換器的GUI程序

【python】使用Selenium獲取(2023博客之星)的參賽文章

【python】使用Selenium和Chrome WebDriver來獲取 【騰訊云 Cloud Studio 實戰訓練營】中的文章信息

使用騰訊云 Cloud studio 實現調度百度AI實現文字識別

【玩轉Python系列【小白必看】Python多線程爬蟲:下載表情包網站的圖片

【玩轉Python系列】【小白必看】使用Python爬取雙色球歷史數據并可視化分析

【玩轉python系列】【小白必看】使用Python爬蟲技術獲取代理IP并保存到文件中

【小白必看】Python圖片合成示例之使用PIL庫實現多張圖片按行列合成

【小白必看】Python爬蟲實戰之批量下載女神圖片并保存到本地

【小白必看】Python詞云生成器詳細解析及代碼實現

【小白必看】Python爬取NBA球員數據示例

【小白必看】使用Python爬取喜馬拉雅音頻并保存的示例代碼

【小白必看】使用Python批量下載英雄聯盟皮膚圖片的技術實現

【小白必看】Python爬蟲數據處理與可視化

【小白必看】輕松獲取王者榮耀英雄皮膚圖片的Python爬蟲程序

【小白必看】利用Python生成個性化名單Word文檔

【小白必看】Python爬蟲實戰:獲取陰陽師網站圖片并自動保存

小白必看系列之圖書管理系統-登錄和注冊功能示例代碼

小白實戰100案例: 完整簡單的雙色球彩票中獎判斷程序,適合小白入門

使用 geopandas 和 shapely(.shp) 進行地理空間數據處理和可視化

使用selenium爬取貓眼電影榜單數據

圖像增強算法Retinex原理與實現詳解

爬蟲入門指南(8): 編寫天氣數據爬蟲程序,實現可視化分析

爬蟲入門指南(7):使用Selenium和BeautifulSoup爬取豆瓣電影Top250實例講解【爬蟲小白必看】

爬蟲入門指南(6):反爬蟲與高級技巧:IP代理、User-Agent偽裝、Cookie繞過登錄驗證及驗證碼識別工具

爬蟲入門指南(5): 分布式爬蟲與并發控制 【提高爬取效率與請求合理性控制的實現方法】

爬蟲入門指南(4): 使用Selenium和API爬取動態網頁的最佳方法

爬蟲入門指南(3):Python網絡請求及常見反爬蟲策略應對方法

爬蟲入門指南(2):如何使用正則表達式進行數據提取和處理

爬蟲入門指南(1):學習爬蟲的基礎知識和技巧

深度學習模型在圖像識別中的應用:CIFAR-10數據集實踐與準確率分析

Python面向對象編程基礎知識和示例代碼

MySQL 數據庫操作指南:學習如何使用 Python 進行增刪改查操作

Python文件操作指南:編碼、讀取、寫入和異常處理

使用Python和Selenium自動化爬取 #【端午特別征文】 探索技術極致,未來因你出“粽” # 的投稿文章

Python多線程與多進程教程:全面解析、代碼案例與優化技巧

Selenium自動化工具集 - 完整指南和使用教程

Python網絡爬蟲基礎進階到實戰教程

Python入門教程:掌握for循環、while循環、字符串操作、文件讀寫與異常處理等基礎知識

Pandas數據處理與分析教程:從基礎到實戰

Python 中常用的數據類型及相關操作詳解

【2023年最新】提高分類模型指標的六大方案詳解

Python編程入門基礎及高級技能、Web開發、數據分析和機器學習與人工智能

用4種回歸方法繪制預測結果圖表:向量回歸、隨機森林回歸、線性回歸、K-最近鄰回歸

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

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

相關文章

NestJs 中使用 mongoose

在 NestJS 中鏈接 MongoDB 有兩種方法。一種方法就是使用TypeORM來進行連接&#xff0c;另外一種方法就是使用Mongoose。 此筆記主要是記錄使用Mongoose的。所以我們先安裝所需的依賴&#xff1a; npm i nestjs/mongoose mongoose安裝完成后&#xff0c;需要在AppModule中引入…

SpringBoot后端服務開啟Https協議提供訪問(使用阿里云資源)

目錄 概述 申請/下載證書 部署證書 本地測試訪問 服務器部署訪問 最后/擴展 總結 概述 本篇博客說明如何將SpringBoot項目開啟Https協議提供訪問。 博文以步驟【申請/下載證書】&#xff0c;【部署證書】&#xff0c;【本地測試訪問】&#xff0c;【服務器部署訪問】 &a…

SIP/VoIP之常見的視頻問題

除了語音通話外&#xff0c;視頻通話也是SIP協議通話中重要的功能&#xff0c;在實際應用中&#xff0c;經常會遇到一些視頻問題&#xff0c;如下&#xff08;以h264為例&#xff09; 一、 己方未顯示對方視頻圖像 排查方法&#xff1a; 查看網絡抓包中有沒有發給已方的視頻…

LORA開發板采集溫濕度數據,連接PC上位機顯示和液晶屏顯示

一、準備材料 準備以下板子和器件 Lora開發板x2 USB數據線x2 OLED 屏幕x2 StLink下載器x1 母對母杜邦線x3 DHT11 x2 二、設備連接 如圖所示先將OLED 屏幕插入到開發板中 接著按照圖中所示的&#xff0c;將串口一以及lora的撥碼開關撥到指定方向 接著將USB數據線一端插入到…

SQL Server用sql語句添加列,添加列注釋

SQL Server用sql語句添加列&#xff0c;添加列注釋 微軟文檔&#xff1a; https://learn.microsoft.com/zh-cn/sql/relational-databases/tables/add-columns-to-a-table-database-engine?viewsql-server-ver15 alter table article add RedirectURL varchar(600) nu…

(七)Unity VR項目升級至Vision Pro需要做的工作

Vision Pro 概述 定位為混合現實眼鏡&#xff0c;對AR支持更友好 無手柄&#xff0c;支持手&#xff08;手勢&#xff09;、眼&#xff08;注視&#xff09;、語音交互 支持空間音頻&#xff0c;相比立體聲、環繞聲更有沉浸感和空間感 支持VR/AR應用&#xff0c;支持多種應用模…

八字精批API接口

接口平臺&#xff1a;https://api.yuanfenju.com/ 開發文檔&#xff1a;https://doc.yuanfenju.com/ 支持格式&#xff1a;JSON 請求方式&#xff1a;HTTP POST <?php//密鑰 $api_secret "wD******XhOUW******pvr"; //請求網關 $gateway_host_url "ht…

FPGA應用學習筆記-----復位電路(二)和小結

不可復位觸發器若和可復位觸發器混合寫的話&#xff0c;不可復位觸發器是由可復位觸發器饋電的。 不應該出現的復位&#xff0c;因為延時導致了冒險&#xff0c;異步復位存在靜態冒險 附加素隱含項&#xff0c;利用數電方法&#xff0c;消除靜態冒險 這樣多時鐘區域還是算異步的…

【Docker】如何在設計 dockerfile 過程中,設置容器啟動后的定時任務

如何在設計 dockerfile 過程中&#xff0c;設置容器啟動后的定時任務 jwensh 2023.08.14 文章目錄 如何在設計 dockerfile 過程中&#xff0c;設置容器啟動后的定時任務1. 基于 alpine 設計 dockerfile 過程中&#xff0c;設置容器啟動后的定時任務2. 基于 CentOS 設計 Dockerf…

深度學習實戰基礎案例——卷積神經網絡(CNN)基于SqueezeNet的眼疾識別|第1例

文章目錄 前言一、數據準備1.1 數據集介紹1.2 數據集文件結構 二、項目實戰2.1 數據標簽劃分2.2 數據預處理2.3 構建模型2.4 開始訓練2.5 結果可視化 三、數據集個體預測 前言 SqueezeNet是一種輕量且高效的CNN模型&#xff0c;它參數比AlexNet少50倍&#xff0c;但模型性能&a…

Linkedin為什么要退出中國市場?

在迅速發展的時代,職場也在不斷變換,只有不斷地提升專業技能和進行培訓,才能在職場中獲得成功。Linkedin作為一家專注于職業發展的平臺,專業的學習體驗以及熱門技能贏得了人們青睞。然而遺憾的是這個曾經讓人備受青睞的平臺,如今卻在中國市場中黯然落幕,究竟是何種原因讓曾經風…

大數據Flink(六十一):Flink流處理程序流程和項目準備

文章目錄 Flink流處理程序流程和項目準備 一、Flink流處理程序的一般流程

Springboot 設置統一的請求返回格式

現在開發過程中主要采用前后端分離的方式進行開發測試&#xff0c;也就是前端封裝請求&#xff0c;后端提供標準的API接口服務。一般現在json 格式受到開發者們的青睞&#xff0c;學習過程中我們可以設置接口的返回類型&#xff0c;那么怎么做到設置統一的返回格式呢&#xff1…

數據在內存中的存儲(二進制形式存儲)

計算機要處理的信息是多種多樣的&#xff0c;如數字、文字、符號、圖形、音頻、視頻等&#xff0c;這些信息在人們的眼里是不同的。但對于計算機來說&#xff0c;它們在內存中都是一樣的&#xff0c;都是以二進制的形式來表示。 要想學習編程&#xff0c;就必須了解二進制&…

Spark SQL優化:NOT IN子查詢優化解決

背景 有如下的數據查詢場景。 SELECT a,b,c,d,e,f FROM xxx.BBBB WHERE dt ${zdt.addDay(0).format(yyyy-MM-dd)} AND predict_type not IN ( SELECT distinct a FROM xxx.AAAAAWHERE dt ${zdt.addDay(0).format(yyyy-MM-dd)} ) 分析 通過查看SQL語句的執行計劃基本…

Dubbo基礎學習(筆記一)

目錄 第一章、概念介紹1.1&#xff09;什么是RPC框架1.2&#xff09;什么是分布式系統1.3&#xff09;Dubbo概述1.3&#xff09;Dubbo基本架構 第二章、服務提供者2.1&#xff09;目錄結構和依賴2.2&#xff09;model層2.3&#xff09;service層2.4&#xff09;resources配置文…

ARTS 挑戰打卡的第8天 ---volatile 關鍵字在MCU中的作用,四個實例講解(Tips)

前言 &#xff08;1&#xff09;volatile 關鍵字作為嵌入式面試的常考點&#xff0c;很多人都不是很了解&#xff0c;或者說一知半解。 &#xff08;2&#xff09;可能有些人會說了&#xff0c;volatile 關鍵字不就是防止編譯器優化的嗎&#xff1f;有啥好詳細講解的&#xff1…

HashMap底層相關內容

HashMap的底層結構&#xff1a; 1.7之前 數組加鏈表&#xff0c;當兩個值進行插入的時候 采用頭插法進行插入&#xff0c;可能會造成死循環 1.8之后 數組加鏈表/紅黑樹&#xff0c;當兩個值進行插入的時候&#xff0c;采用尾插法進行插入&#xff0c;不會造成死循環 HashMap底…

xml轉map工具類

背景&#xff1a;最近遇到接口返回是xml&#xff0c;所以需要整一個轉換的工具類&#xff0c;方便后續其他xml處理。 依賴引入&#xff1a; <dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.1</versi…

澎峰科技|邀您關注2023 RISC-V中國峰會!

峰會概覽 2023 RISC-V中國峰會&#xff08;RISC-V Summit China 2023&#xff09;將于8月23日至25日在北京香格里拉飯店舉行。本屆峰會將以“RISC-V生態共建”為主題&#xff0c;結合當下全球新形勢&#xff0c;把握全球新時機&#xff0c;呈現RISC-V全球新觀點、新趨勢。 本…