天天看點

什麼是python全棧開發_Python全棧開發之

1、什麼叫疊代

現在,我們已經獲得了一個新線索,有一個叫做“可疊代的”概念。

首先,我們從報錯來分析,好像之是以1234不可以for循環,是因為它不可疊代。那麼如果“可疊代”,就應該可以被for循環了。

這個我們知道呀,字元串、清單、元組、字典、集合都可以被for循環,說明他們都是可疊代的。

我們怎麼來證明這一點呢?

1 from collections importIterable2

3 l = [1,2,3,4]4 t = (1,2,3,4)5 d = {1:2,3:4}6 s = {1,2,3,4}7

8 print(isinstance(l,Iterable))9 print(isinstance(t,Iterable))10 print(isinstance(d,Iterable))11 print(isinstance(s,Iterable))

結合我們使用for循環取值的現象,再從字面上了解一下,其實疊代就是我們剛剛說的,可以将某個資料集内的資料“一個挨着一個的取出來”,就叫做疊代。

2、疊代器和協定

既什麼叫“可疊代”之後,又一個曆史新難題,什麼叫“疊代器”?

雖然我們不知道什麼叫疊代器,但是我們現在已經有一個疊代器了,這個疊代器是一個清單的疊代器。

我們來看看這個清單的疊代器比起清單來說實作了哪些新方法,這樣就能揭開疊代器的神秘面紗了吧?

1 '''

2 dir([1,2].__iter__())是清單疊代器中實作的所有方法,dir([1,2])是清單中實作的所有方法,都是以清單的形式傳回給我們的,為了看的更清楚,我們分别把他們轉換成集合,3 然後取差集。4 '''

5 #print(dir([1,2].__iter__()))

6 #print(dir([1,2]))

7 print(set(dir([1,2].__iter__()))-set(dir([1,2])))8

9 結果:10 {'__length_hint__', '__next__', '__setstate__'}11

12

13 iter_l = [1,2,3,4,5,6].__iter__()14 #擷取疊代器中元素的長度

15 print(iter_l.__length_hint__())16 #根據索引值指定從哪裡開始疊代

17 print('*',iter_l.__setstate__(4))18 #一個一個的取值

19 print('**',iter_l.__next__())20 print('***',iter_l.__next__())

這三個方法中,能讓我們一個一個取值的神奇方法是誰?

沒錯!就是__next__

在for循環中,就是在内部調用了__next__方法才能取到一個一個的值。

那接下來我們就用疊代器的next方法來寫一個不依賴for的周遊。

1 l = [1,2,3,4]2 l_iter = l.__iter__()3 item = l_iter.__next__()4 print(item)5 item = l_iter.__next__()6 print(item)7 item = l_iter.__next__()8 print(item)9 item = l_iter.__next__()10 print(item)11 item = l_iter.__next__()12 print(item)

這是一段會報錯的代碼,如果我們一直取next取到疊代器裡已經沒有元素了,就會抛出一個異常StopIteration,告訴我們,清單中已經沒有有效的元素了。

這個時候,我們就要使用異常處理機制來把這個異常處理掉。

1 l = [1,2,3,4]2 l_iter = l.__iter__()3 whileTrue:4 try:5 item = l_iter.__next__()6 print(item)7 exceptStopIteration:8 break

3、可疊代對象

我們現在是從結果分析原因,能被for循環的就是“可疊代的”,但是如果正着想,for怎麼知道誰是可疊代的呢?

假如我們自己寫了一個資料類型,希望這個資料類型裡的東西也可以使用for被一個一個的取出來,那我們就必須滿足for的要求。這個要求就叫做“協定”。

可以被疊代要滿足的要求就叫做可疊代協定。可疊代協定的定義非常簡單,就是内部實作了__iter__方法。

疊代器生成的對象就是可疊代對象

4、生成器

Python中提供的生成器:

1.生成器函數:正常函數定義,但是,使用yield語句而不是return語句傳回結果。yield語句一次傳回一個結果,在每個結果中間,挂起函數的狀态,以便下次重它離開的地方繼續執行

2.生成器表達式:類似于清單推導,但是,生成器傳回按需産生結果的一個對象,而不是一次建構一個結果清單

生成器Generator:

本質:疊代器(是以自帶了__iter__方法和__next__方法,不需要我們去實作)

特點:惰性運算,開發者自定義

1 importtime2 defgenrator_fun1():3 a = 1

4 print('現在定義了a變量')5 yielda6 b = 2

7 print('現在又定義了b變量')8 yieldb9

10 g1 =genrator_fun1()11 print('g1 :',g1) #列印g1可以發現g1就是一個生成器

12 print('-'*20) #我是華麗的分割線

13 print(next(g1))14 time.sleep(1) #sleep一秒看清執行過程

15 print(next(g1))

1 defgenerator():2 print(123)3 content = yield 1

4 print('=======',content)5 print(456)6 yield27

8 g =generator()9 ret = g.__next__()10 print('***',ret)11 ret = g.send('hello') #send的效果和next一樣

12 print('***',ret)13

14 #send 擷取下一個值的效果和next基本一緻

15 #隻是在擷取下一個值的時候,給上一yield的位置傳遞一個資料

16 #使用send的注意事項

17 #第一次使用生成器的時候 是用next擷取下一個值

18 #最後一個yield不能接受外部的值

1 #yield from

2

3 defgen1():4 for c in 'AB':5 yieldc6 for i in range(3):7 yieldi8

9 print(list(gen1()))10

11 defgen2():12 yield from 'AB'

13 yield from range(3)14

15 print(list(gen2()))16

17 yield from