python序列化反序列化和異常處理筆記_第1頁
python序列化反序列化和異常處理筆記_第2頁
python序列化反序列化和異常處理筆記_第3頁
python序列化反序列化和異常處理筆記_第4頁
python序列化反序列化和異常處理筆記_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、迭代器迭代是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象。迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器只能往前不會后退。1. 可迭代對象我們已經(jīng)知道可以對list、tuple、str等類型的數(shù)據(jù)使用for.in.的循環(huán)語法從其中依次拿到數(shù)據(jù)進(jìn)行使用,我們把這樣的過程稱為遍歷,也叫迭代。但是,是否所有的數(shù)據(jù)類型都可以放到for.in.的語句中,然后讓for.in.每次從中取出一條數(shù)據(jù)供我們使用,即供我們迭代嗎? for i in 100:. print(i).Traceback (most recent call last): File , line

2、1, in TypeError: int object is not iterable# int整型不是iterable,即int整型不是可以迭代的我們把可以通過for.in.這類語句迭代讀取一條數(shù)據(jù)供我們使用的對象稱之為可迭代對象(Iterable)。2. 如何判斷一個對象是否可以迭代可以使用 isinstance() 判斷一個對象是否是 Iterable 對象:In 50: from collections import IterableIn 51: isinstance(, Iterable)Out51: TrueIn 52: isinstance(, Iterable)Out52: T

3、rueIn 53: isinstance(abc, Iterable)Out53: TrueIn 54: isinstance(mylist, Iterable)Out54: FalseIn 55: isinstance(100, Iterable)Out55: False3. 可迭代對象的本質(zhì)我們分析對可迭代對象進(jìn)行迭代使用的過程,發(fā)現(xiàn)每迭代一次(即在for.in.中每循環(huán)一次)都會返回對象中的下一條數(shù)據(jù),一直向后讀取數(shù)據(jù)直到迭代了所有數(shù)據(jù)后結(jié)束。那么,在這個過程中就應(yīng)該有一個“人”去記錄每次訪問到了第幾條數(shù)據(jù),以便每次迭代都可以返回下一條數(shù)據(jù)。我們把這個能幫助我們進(jìn)行數(shù)據(jù)迭代的“人”稱為迭

4、代器(Iterator)??傻鷮ο蟮谋举|(zhì)就是可以向我們提供一個這樣的中間“人”即迭代器幫助我們對其進(jìn)行迭代遍歷使用。可迭代對象通過_iter_方法向我們提供一個迭代器,我們在迭代一個可迭代對象的時候,實際上就是先獲取該對象提供的一個迭代器,然后通過這個迭代器來依次獲取對象中的每一個數(shù)據(jù).那么也就是說,一個具備了_iter_方法的對象,就是一個可迭代對象。from collections.abc import Iterableclass Demo(object): def _init_(self, n): self.n = n self.current = 0 def _iter_(self)

5、: passdemo = Demo(10)print(isinstance(demo, Iterable) # Truefor d in demo: # 重寫了 _iter_ 方法以后,demo就是一個一個可迭代對象了,可以放在for.in的后面 print(d)# 此時再使用for.in循環(huán)遍歷,會提示 TypeError: iter() returned non-iterator of type NoneType# 這是因為,一個可迭代對象如果想要被for.in循環(huán),它必須要有一個迭代器4. 迭代器Iterator通過上面的分析,我們已經(jīng)知道,迭代器是用來幫助我們記錄每次迭代訪問到的位置,

6、當(dāng)我們對迭代器使用next()函數(shù)的時候,迭代器會向我們返回它所記錄位置的下一個位置的數(shù)據(jù)。實際上,在使用next()函數(shù)的時候,調(diào)用的就是迭代器對象的_next_方法(Python3中是對象的_next_方法,Python2中是對象的next()方法)。所以,我們要想構(gòu)造一個迭代器,就要實現(xiàn)它的next方法。但這還不夠,python要求迭代器本身也是可迭代的,所以我們還要為迭代器實現(xiàn)_iter_方法,而_iter_方法要返回一個迭代器,迭代器自身正是一個迭代器,所以迭代器的_iter_方法返回自身即可。一個實現(xiàn)了iter方法和next方法的對象,就是迭代器。class MyIterator(

7、object): def _init_(self, n): self.n = n self.current = 0 # 自定義迭代器需要重寫_iter_和_next_方法 def _iter_(self): return self def _next_(self): if self.current self.n: value = self.current self.current += 1 return value else: raise StopIterationmy_it = MyIterator(10)for i in my_it: # 迭代器重寫了_iter_方法,它本身也是一個可迭代

8、對象 print(i)5. 如何判斷一個對象是否是迭代器調(diào)用一個對象的_iter_方法,或者調(diào)用iter()內(nèi)置函數(shù),可以獲取到一個可迭代對象的迭代器。names = hello, good, yesprint(names._iter_() # 調(diào)用對象的_iter_()方法print(iter(names) # 調(diào)用iter()內(nèi)置函數(shù)可以使用 isinstance() 判斷一個對象是否是 Iterator 對象:from collections.abc import Iteratornames = hello, good, yesprint(isinstance(iter(names),

9、Iterator)6. for.in.循環(huán)的本質(zhì)foriteminIterable循環(huán)的本質(zhì)就是先通過iter()函數(shù)獲取可迭代對象Iterable的迭代器,然后對獲取到的迭代器不斷調(diào)用next()方法來獲取下一個值并將其賦值給item,當(dāng)遇到StopIteration的異常后循環(huán)結(jié)束。7. 迭代器的應(yīng)用場景我們發(fā)現(xiàn)迭代器最核心的功能就是可以通過next()函數(shù)的調(diào)用來返回下一個數(shù)據(jù)值。如果每次返回的數(shù)據(jù)值不是在一個已有的數(shù)據(jù)集合中讀取的,而是通過程序按照一定的規(guī)律計算生成的,那么也就意味著可以不用再依賴一個已有的數(shù)據(jù)集合,也就是說不用再將所有要迭代的數(shù)據(jù)都一次性緩存下來供后續(xù)依次讀取,這樣可

10、以節(jié)省大量的存儲(內(nèi)存)空間。舉個例子,比如,數(shù)學(xué)中有個著名的斐波拉契數(shù)列(Fibonacci),數(shù)列中第一個數(shù)為0,第二個數(shù)為1,其后的每一個數(shù)都可由前兩個數(shù)相加得到:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, .現(xiàn)在我們想要通過for.in.循環(huán)來遍歷迭代斐波那契數(shù)列中的前n個數(shù)。那么這個斐波那契數(shù)列我們就可以用迭代器來實現(xiàn),每次迭代都通過數(shù)學(xué)計算來生成下一個數(shù)。class FibIterator(object): 斐波那契數(shù)列迭代器 def _init_(self, n): :param n: int, 指明生成數(shù)列的前n個數(shù) self.n = n # curren

11、t用來保存當(dāng)前生成到數(shù)列中的第幾個數(shù)了 self.current = 0 # num1用來保存前前一個數(shù),初始值為數(shù)列中的第一個數(shù)0 self.num1 = 0 # num2用來保存前一個數(shù),初始值為數(shù)列中的第二個數(shù)1 self.num2 = 1 def _next_(self): 被next()函數(shù)調(diào)用來獲取下一個數(shù) if self.current self.n: num = self.num1 self.num1, self.num2 = self.num2, self.num1+self.num2 self.current += 1 return num else: raise Stop

12、Iteration def _iter_(self): 迭代器的_iter_返回自身即可 return selfif _name_ = _main_: fib = FibIterator(10) for num in fib: print(num, end= )生成器1. 生成器利用迭代器,我們可以在每次迭代獲取數(shù)據(jù)(通過next()方法)時按照特定的規(guī)律進(jìn)行生成。但是我們在實現(xiàn)一個迭代器時,關(guān)于當(dāng)前迭代到的狀態(tài)需要我們自己記錄,進(jìn)而才能根據(jù)當(dāng)前狀態(tài)生成下一個數(shù)據(jù)。為了達(dá)到記錄當(dāng)前狀態(tài),并配合next()函數(shù)進(jìn)行迭代使用,我們可以采用更簡便的語法,即生成器(generator)。生成器是一類特

13、殊的迭代器。2. 創(chuàng)建生成器方法1要創(chuàng)建一個生成器,有很多種方法。第一種方法很簡單,只要把一個列表生成式的 改成 ( )In 15: L = x*2 for x in range(5)In 16: LOut16: 0, 2, 4, 6, 8In 17: G = ( x*2 for x in range(5)In 18: GOut18: generator object at 0 x7f626c132db0In 19:創(chuàng)建 L 和 G 的區(qū)別僅在于最外層的 和 ( ) , L 是一個列表,而 G 是一個生成器。我們可以直接打印出列表L的每一個元素,而對于生成器G,我們可以按照迭代器的使用方法來使

14、用,即可以通過next()函數(shù)、for循環(huán)、list()等方法使用。In 19: next(G)Out19: 0In 20: next(G)Out20: 2In 21: next(G)Out21: 4In 22: next(G)Out22: 6In 23: next(G)Out23: 8In 24: next(G)StopIteration Traceback (most recent call last) in () 1 next(G)StopIteration:In 25:In 26: G = ( x*2 for x in range(5)In 27: for x in G: : prin

15、t(x) : 02468In 28:3. 創(chuàng)建生成器方法2generator非常強(qiáng)大。如果推算的算法比較復(fù)雜,用類似列表生成式的 for 循環(huán)無法實現(xiàn)的時候,還可以用函數(shù)來實現(xiàn)。我們?nèi)匀挥蒙弦还?jié)提到的斐波那契數(shù)列來舉例,回想我們在上一節(jié)用迭代器的實現(xiàn)方式:class FibIterator(object): 斐波那契數(shù)列迭代器 def _init_(self, n): :param n: int, 指明生成數(shù)列的前n個數(shù) self.n = n # current用來保存當(dāng)前生成到數(shù)列中的第幾個數(shù)了 self.current = 0 # num1用來保存前前一個數(shù),初始值為數(shù)列中的第一個數(shù)0 s

16、elf.num1 = 0 # num2用來保存前一個數(shù),初始值為數(shù)列中的第二個數(shù)1 self.num2 = 1 def _next_(self): 被next()函數(shù)調(diào)用來獲取下一個數(shù) if self.current self.n: num = self.num1 self.num1, self.num2 = self.num2, self.num1+self.num2 self.current += 1 return num else: raise StopIteration def _iter_(self): 迭代器的_iter_返回自身即可 return self注意,在用迭代器實現(xiàn)的方

17、式中,我們要借助幾個變量(n、current、num1、num2)來保存迭代的狀態(tài)?,F(xiàn)在我們用生成器來實現(xiàn)一下。In 30: def fib(n): : current = 0 : num1, num2 = 0, 1 : while current n: : yield num1 : num1, num2 = num2, num1+num2 : current += 1 : return done :In 31: F = fib(5)In 32: next(F)Out32: 1In 33: next(F)Out33: 1In 34: next(F)Out34: 2In 35: next(F)O

18、ut35: 3In 36: next(F)Out36: 5In 37: next(F)StopIteration Traceback (most recent call last) in () 1 next(F)StopIteration: done在使用生成器實現(xiàn)的方式中,我們將原本在迭代器_next_方法中實現(xiàn)的基本邏輯放到一個函數(shù)中來實現(xiàn),但是將每次迭代返回數(shù)值的return換成了yield,此時新定義的函數(shù)便不再是函數(shù),而是一個生成器了。簡單來說:只要在def中有yield關(guān)鍵字的 就稱為 生成器此時按照調(diào)用函數(shù)的方式( 案例中為F = fib(5) )使用生成器就不再是執(zhí)行函數(shù)體了,

19、而是會返回一個生成器對象( 案例中為F ),然后就可以按照使用迭代器的方式來使用生成器了。In 38: for n in fib(5): : print(n) : 11235In 39:但是用for循環(huán)調(diào)用generator時,發(fā)現(xiàn)拿不到generator的return語句的返回值。如果想要拿到返回值,必須捕獲StopIteration錯誤,返回值包含在StopIteration的value中:In 39: g = fib(5)In 40: while True: : try: : x = next(g) : print(value:%d%x) : except StopIteration a

20、s e: : print(生成器返回值:%s%e.value) : break : value:1value:1value:2value:3value:5生成器返回值:doneIn 41:總結(jié)使用了yield關(guān)鍵字的函數(shù)不再是函數(shù),而是生成器。(使用了yield的函數(shù)就是生成器)yield關(guān)鍵字有兩點作用:保存當(dāng)前運(yùn)行狀態(tài)(斷點),然后暫停執(zhí)行,即將生成器(函數(shù))掛起將yield關(guān)鍵字后面表達(dá)式的值作為返回值返回,此時可以理解為起到了return的作用可以使用next()函數(shù)讓生成器從斷點處繼續(xù)執(zhí)行,即喚醒生成器(函數(shù))Python3中的生成器可以使用return返回最終運(yùn)行的返回值,而Pyt

21、hon2中的生成器不允許使用return返回一個返回值(即可以使用return從生成器中退出,但return后不能有任何表達(dá)式)。4. 使用send喚醒我們除了可以使用next()函數(shù)來喚醒生成器繼續(xù)執(zhí)行外,還可以使用send()函數(shù)來喚醒執(zhí)行。使用send()函數(shù)的一個好處是可以在喚醒的同時向斷點處傳入一個附加數(shù)據(jù)。例子:執(zhí)行到y(tǒng)ield時,gen函數(shù)作用暫時保存,返回i的值; temp接收下次c.send(python),send發(fā)送過來的值,c.next()等價c.send(None)In 10: def gen(): : i = 0 : while i5: : temp = yield

22、 i : print(temp) : i+=1 :使用sendIn 43: f = gen()In 44: next(f)Out44: 0In 45: f.send(haha)hahaOut45: 1In 46: next(f)NoneOut46: 2In 47: f.send(haha)hahaOut47: 3In 48:使用next函數(shù)In 11: f = gen()In 12: next(f)Out12: 0In 13: next(f)NoneOut13: 1In 14: next(f)NoneOut14: 2In 15: next(f)NoneOut15: 3In 16: next(f

23、)NoneOut16: 4In 17: next(f)NoneStopIteration Traceback (most recent call last) in () 1 next(f)StopIteration:使用_next_()方法(不常使用)In 18: f = gen()In 19: f._next_()Out19: 0In 20: f._next_()NoneOut20: 1In 21: f._next_()NoneOut21: 2In 22: f._next_()NoneOut22: 3In 23: f._next_()NoneOut23: 4In 24: f._next_()

24、NoneStopIteration Traceback (most recent call last) in () 1 f._next_()StopIteration:property屬性property屬性是一種用起來像是實例屬性一樣的特殊屬性,可以對應(yīng)于某個方法。class Foo: def func(self): pass # 定義property屬性 property def prop(self): pass# # 調(diào)用 #foo_obj = Foo()foo_obj.func() # 調(diào)用實例方法foo_p # 調(diào)用property屬性property屬性的定義和調(diào)用要

25、注意一下幾點:定義時,在實例方法的基礎(chǔ)上添加 property 裝飾器;并且僅有一個self參數(shù)調(diào)用時,無需括號 方法:foo_obj.func() property屬性:foo_p簡單的實例對于京東商城中顯示電腦主機(jī)的列表頁面,每次請求不可能把數(shù)據(jù)庫中的所有內(nèi)容都顯示到頁面上,而是通過分頁的功能局部顯示,所以在向數(shù)據(jù)庫中請求數(shù)據(jù)時就要顯示的指定獲取從第m條到第n條的所有數(shù)據(jù) 這個分頁的功能包括:根據(jù)用戶請求的當(dāng)前頁和總數(shù)據(jù)條數(shù)計算出 m 和 n根據(jù)m 和 n 去數(shù)據(jù)庫中請求數(shù)據(jù)# # 定義 #class Pager: def _init_(self, current_page)

26、: # 用戶當(dāng)前請求的頁碼(第一頁、第二頁.) self.current_page = current_page # 每頁默認(rèn)顯示10條數(shù)據(jù) self.per_items = 10 property def start(self): val = (self.current_ 1) * self.per_items return val property def end(self): val = self.current_page * self.per_items return val# # 調(diào)用 #p = Pager(1)p.start # 就是起始值,即:mp.end # 就是結(jié)束值,即:n

27、從上述可見Python的property屬性的功能是:property屬性內(nèi)部進(jìn)行一系列的邏輯計算,最終將計算結(jié)果返回。property屬性的兩種方式裝飾器 即:在方法上應(yīng)用裝飾器類屬性 即:在類中定義值為property對象的類屬性裝飾器方式在類的實例方法上應(yīng)用property裝飾器Python中的類有經(jīng)典類和新式類,新式類的屬性比經(jīng)典類的屬性豐富。( 如果類繼object,那么該類是新式類 )經(jīng)典類的實現(xiàn):class Goods: property def price(self): return laowangobj = Goods()result = obj.price # 自動執(zhí)行 p

28、roperty 修飾的 price 方法,并獲取方法的返回值print(result)新式類的實現(xiàn):class Goods: 只有在python3中才有xxx.setter xxx.deleter def _init_(self): # 原價 self.original_price = 100 # 折扣 self.discount = 0.8 property def price(self): new_price = self.original_price * self.discount return new_price price.setter def price(self, value): self.original_price = value price.deleter def price(self): del self.original_priceobj = Goods()obj.price # 獲取商品價格obj.price = 200 # 修改商品原價del obj.price # 刪除商品原價總結(jié)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論