文章目錄
- 高階函數
- 定義一個變量指向函數
- 高階函數
- 函數做為另一個函數的參數
- 函數作為另一個函數的返回值
- 閉包
- 函數嵌套
- 什么是閉包
- 修改外部變量的值
- 原因分析
- 解決方案
- 進階案例
高階函數
在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-最近鄰回歸