詳解Python中的三器一閉
迭代器
什么是迭代
迭代是重復(fù)反饋過程的活動,其目的通常是為了逼近所需目標(biāo)或結(jié)果。每一次對過程的重復(fù)稱為一次“迭代”,而每一次迭代得到的結(jié)果會作為下一次迭代的初始值。
在python中,迭代是訪問集合元素的一種方式。對list、tuple、str等類型的數(shù)據(jù)使用for…in…的循環(huán)語法從其中依次拿到數(shù)據(jù)進(jìn)行使用,我們把這樣的過程稱為遍歷,也叫迭代。
什么是可迭代對象
一個對象如果實(shí)現(xiàn)了__iter__方法(魔法方法),那么我們稱這個對象是可迭代對象。
或者可以這樣理解,只要是可以通過for…in…的形式進(jìn)行遍歷的,那么這個數(shù)據(jù)類型就是可以迭代的。
判斷數(shù)據(jù)是否可迭代
python中要判斷一個對象是否是可迭代的,可以用collections模塊中的Iterable來進(jìn)行判斷。isinstance函數(shù)會返回True或False來表明對象是(True)或者不是(False)可迭代對象。
from collections.abc import Iterable print(isinstance(["abc"], Iterable)) print(isinstance([100], Iterable))
什么是迭代器
迭代器的作用是用來訪問容器(用來保存元素的數(shù)據(jù)結(jié)構(gòu))中的元素,所以使用迭代器,我們就可以訪問容器中里面的元素。
迭代器是一個可以記住遍歷的位置的對象。迭代器對象從第一個元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器只能往前不會后退。
迭代器的本質(zhì)
我們可以通過iter()函數(shù)獲取這些可迭代對象的迭代器。然后我們可以對獲取到的迭代器不斷使用next()函數(shù)來獲取下一條數(shù)據(jù)。
使用迭代器取數(shù)據(jù)
from collections.abc import Iterator nums = [3, 6, 8] # 可迭代對象 nums = iter(nums) # 創(chuàng)建了迭代器 print("nums", isinstance(nums, Iterator)) # 判斷是否是迭代器 # 取出迭代器的數(shù)據(jù) num1 = next(nums) print(num1) num1 = next(nums) print(num1) num1 = next(nums) print(num1)
若迭代的次數(shù)超過了可迭代對象的長度, 就會報StopIteration異常。
自定義迭代器
使用__iter__和__next__方法自定義迭代器
只要在類中,定義__iter__方法,那么這個類創(chuàng)建出來的對象一定是可迭代對象
如果類中實(shí)現(xiàn)了__iter__方法和__next__方法的對象,就是迭代器。
當(dāng)我們調(diào)用iter()函數(shù)提取一個可迭代對象的 迭代器時,實(shí)際上會自動調(diào)用這個對象的__iter__方法,并且這個方法返回迭代器。
# 使用迭代器完成學(xué)生管理系統(tǒng) class StuSystem(object): """ 學(xué)生管理系統(tǒng) """ def __init__(self): self.stus = [] self.current_num = 0 def add(self): """ 添加一個新的學(xué)生 :return: """ name = input("請輸入新學(xué)生的姓名:") tel = input("請輸入新學(xué)生的手機(jī)號:") address = input("請輸入新學(xué)生的住址:") new_stu = dict() new_stu["name"] = name new_stu["tel"] = tel new_stu["address"] = address self.stus.append(new_stu) def __iter__(self): return self def __next__(self): if self.current_num < len(self.stus): ret = self.stus[self.current_num] self.current_num += 1 return ret else: self.current_num = 0 raise StopIteration # 創(chuàng)建對象 stu = StuSystem() # 添加信息 stu.add() stu.add() stu.add() stus = [x for x in stu] print(stus)
凡是可作用于for循環(huán)的對象都是Iterable 類型; 凡是可作用于 next() 函數(shù)的對象都是Iterator 類型; 集合數(shù)據(jù)類型如list 、dict、str等是 Iterable但不是Iterator,不過可以通過 iter()函數(shù)獲得一個Iterator對象。
生成器
一邊循環(huán)一邊計算的機(jī)制,稱為生成器(generator)
在Python中,使用了yield的函數(shù)被稱為生成器。跟普通函數(shù)不同的是,生成器是一個返回迭代器的函數(shù),只能用于迭代操作。生成器函數(shù)一般是通過for循環(huán)調(diào)用,for循環(huán)自帶next方法。
創(chuàng)建生產(chǎn)器的方法
1.將列表推導(dǎo)式的[]改為()
2.在函數(shù)中使用yield關(guān)鍵字,函數(shù)就變成了一個generator
使用生成器完成斐波那契數(shù)列
def fib_generator(): num1 = 1 num2 = 1 while True: temp_num = num1 num1, num2 = num2, num1+num2 # return temp_num # 方式1代碼 yield temp_num # 方式1代碼(方式1不能夠生成1,1,2,3,5...斐波那契數(shù)列) # print(fib_generator()) # print(fib_generator()) # print(fib_generator()) # print(fib_generator()) # 方式2代碼(可以生成斐波那契數(shù)列) fib = fib_generator() print(next(fib)) print(next(fib)) print(next(fib)) print(next(fib))
關(guān)鍵字yield
yield是一個類似return的關(guān)鍵字。當(dāng)我們調(diào)用這個函數(shù)的時候并不是返回計算的結(jié)果。而是返回一個生成器。只有迭代這個生成器的時候才會計算結(jié)果。
next和send
next()方法: 在調(diào)用生成器運(yùn)行的過程中,每次遇到 yield ,函數(shù)返回當(dāng)前的值,并且會暫停并保存當(dāng)前所有的運(yùn)行信息, 并在下一次執(zhí)行 next() 方法時從當(dāng)前位置繼續(xù)運(yùn)行。
send()方法: 先理解個概念【休眠】:意思就是暫時保留先不進(jìn)行,等待需要時再進(jìn)行。作用與next()作用相似 區(qū)別:
1.send(value)可以傳遞value給yield,即:我們可以指定yield返回啥就返回啥,
2.next()不能傳遞特定的值,只能傳遞None進(jìn)去。
def genterator_test(): while True: print("--1-") num = yield 100 print("--2--", "num=", num) g = genterator_test() print(g.send(None)) print(g.send(11)) print(g.send(22))
生成器的特點(diǎn): 存儲的是生成數(shù)據(jù)的方式(即算法),而不是存儲生成的數(shù)據(jù),因此節(jié)約內(nèi)存。
裝飾器
裝飾器是給現(xiàn)有的模塊增添新的小功能,可以對原函數(shù)進(jìn)行功能擴(kuò)展,而且還不需要修改原函數(shù)的內(nèi)容,也不需要修改原函數(shù)的調(diào)用。
裝飾器的功能
裝飾器的實(shí)現(xiàn)是由閉包支撐的; 裝飾器本質(zhì)上是?個python函數(shù),它可以在讓其他函數(shù)在不需要做任何代碼的變動的前提下增加額外的功能; 裝飾器的返回值也是?個函數(shù)的對象,它經(jīng)常用于有切面需求的場景,實(shí)現(xiàn)路由傳參,flask的路由傳參依賴于裝飾器,瀏覽器通過url訪問到裝飾器的路由,從而訪問視圖函數(shù)獲得返回的HTML頁面;
定義裝飾器
def check_login(func): def inner(): # 驗(yàn)證1 # 驗(yàn)證2 # 驗(yàn)證3 func() return inner @check_login def f1(): print('f1')
def check_login(func): def inner(): # 驗(yàn)證1 if "admin" != input("請輸入用戶名:"): return "用戶名不正確" # 驗(yàn)證2 if "123456" != input("請輸入密碼:"): return "密碼不正確" # 驗(yàn)證3 if "7788" != input("請輸入手機(jī)短信驗(yàn)證碼:"): return "驗(yàn)證碼不正確" func() return inner @check_login def f1(): print('f1') f1() # 調(diào)用f1函數(shù)
閉包
什么是閉包
如果在一個內(nèi)部函數(shù)里,對在外部作用域(但不是在全局作用域)的變量進(jìn)行引用,那么內(nèi)部函數(shù)就被認(rèn)為是閉包(closure).
# 定義函數(shù)可以理解為: # 定義了一個全局變量,其變量名字是函數(shù)的名字,即test # 這個test變量指向了一個代碼塊,這個代碼塊是函數(shù) # 其實(shí)就是說test保存了一個代碼塊的地址,即引用 def test(): print("--- in test func----") test() # 這是調(diào)用函數(shù) ret = test # 用另外一個變量 復(fù)制了 test這個引用,導(dǎo)致ret變量也指向那個 函數(shù)代碼塊 # 下面輸出的2個地址信息是相同的 print(id(ret)) print(id(test)) # 通過引用調(diào)用函數(shù) ret()
函數(shù)、匿名函數(shù)、閉包、對象 當(dāng)做實(shí)參時的區(qū)別
匿名函數(shù)能夠完成基本的簡單功能,,,傳遞是這個函數(shù)的引用 只有功能
普通函數(shù)能夠完成較為復(fù)雜的功能,,,傳遞是這個函數(shù)的引用 只有功能
閉包能夠?qū)⑤^為復(fù)雜的功能,,,傳遞是這個閉包中的函數(shù)以及數(shù)據(jù),因此傳遞是功能+數(shù)據(jù)
對象能夠完成最為復(fù)雜的功能,,,傳遞是很多數(shù)據(jù)+很多功能,因此傳遞是功能+數(shù)據(jù)
到此這篇關(guān)于詳解Python中的三器一閉的文章就介紹到這了,更多相關(guān)Python三器一閉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python數(shù)據(jù)處理實(shí)戰(zhàn)(必看篇)
下面小編就為大家?guī)硪黄猵ython數(shù)據(jù)處理實(shí)戰(zhàn)(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06Python文件監(jiān)聽工具pyinotify與watchdog實(shí)例
今天小編就為大家分享一篇關(guān)于Python文件監(jiān)聽工具pyinotify與watchdog實(shí)例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10在python中使用requests 模擬瀏覽器發(fā)送請求數(shù)據(jù)的方法
今天小編就為大家分享一篇在python中使用requests 模擬瀏覽器發(fā)送請求數(shù)據(jù)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12python編程調(diào)用設(shè)備串口發(fā)送數(shù)據(jù)方式
這篇文章主要介紹了python編程調(diào)用設(shè)備串口發(fā)送數(shù)據(jù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09Python實(shí)現(xiàn)將藍(lán)底照片轉(zhuǎn)化為白底照片功能完整實(shí)例
這篇文章主要介紹了Python實(shí)現(xiàn)將藍(lán)底照片轉(zhuǎn)化為白底照片功能,結(jié)合完整實(shí)例形式分析了Python基于cv2庫進(jìn)行圖形轉(zhuǎn)換操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-12-12Python數(shù)據(jù)結(jié)構(gòu)之棧、隊(duì)列的實(shí)現(xiàn)代碼分享
這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)之棧、隊(duì)列的實(shí)現(xiàn)代碼分享,具有一定參考價值,需要的朋友可以了解下。2017-12-12Python設(shè)計模式之解釋器模式原理與用法實(shí)例分析
這篇文章主要介紹了Python設(shè)計模式之解釋器模式原理與用法,結(jié)合具體實(shí)例形式分析了解釋器模式的概念、原理、定義及使用方法,需要的朋友可以參考下2019-01-01Python使用itchat模塊實(shí)現(xiàn)簡單的微信控制電腦功能示例
這篇文章主要介紹了Python使用itchat模塊實(shí)現(xiàn)簡單的微信控制電腦功能,結(jié)合實(shí)例形式分析了Python基于itchat模塊控制電腦實(shí)現(xiàn)運(yùn)行程序、截圖等相關(guān)操作技巧,需要的朋友可以參考下2019-08-08python 實(shí)現(xiàn)多線程下載m3u8格式視頻并使用fmmpeg合并
這篇文章主要介紹了python 實(shí)現(xiàn)多線程下載m3u8格式視頻,使用fmmpeg合并的實(shí)例代碼,需要的朋友可以參考下2019-11-11