乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      【Python之路】特別篇

       highoo 2019-03-20
      生成器(constructor)

        生成器函數(shù)在Python中與迭代器協(xié)議的概念聯(lián)系在一起。包含yield語句的函數(shù)會被特地編譯成生成器 !!!

        當(dāng)函數(shù)被調(diào)用時,他們返回一個生成器對象,這個對象支持迭代器接口。

        不像一般的函數(shù)會生成值后退出,生成器函數(shù)在生成值后會自動掛起并暫停他們的執(zhí)行和狀態(tài),他的本地變量將保存狀態(tài)信息,這些信息在函數(shù)恢復(fù)時將再度有效

      創(chuàng)建生成器方式有兩種:

      方法一:

      1
      s = ( x for x in range(5) )

      方法二:

      1
      2
      3
      def foo():
          print('OK')
          yield 1

      例子:

      1
      2
      3
      4
      5
      6
      def g(n):
          for i in range(n):
              yield i **2
      for i in g(5):
          print(i)

      要了解他的運行原理,我們來用next方法看看:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      t = g(5)
      print(t.__next__())      # 0
      print(t.__next__())      # 1
      print(t.__next__())      # 4
      print(t.__next__())      # 9
      print(t.__next__())      # 16
      print(t.__next__())
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      StopIteration

      在運行完5次next之后,生成器拋出了一個StopIteration異常,迭代終止。

      send(msg) 與 next()

      了解了next()如何讓包含yield的函數(shù)執(zhí)行后,我們再來看另外一個非常重要的函數(shù)send(msg)。

      其實next()和send()在一定意義上作用是相似的,區(qū)別是send()可以傳遞yield表達(dá)式的值進(jìn)去,而next()不能傳遞特定的值,只能傳遞None進(jìn)去。因此,我們可以看做

      c.next() 和 c.send(None) 作用是一樣的。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      def g(n):
          for i in range(n):
              ret = yield i **2
              print(ret)
      t = g(5)
      print(t.__next__())
      print(t.send('Hello'))
      # 0 Hello 1

      需要注意的是,第一次調(diào)用時,請使用next()語句或是send(None),不能使用send發(fā)送一個非None的值,否則會出錯的,因為沒有yield語句來接收這個值。

      send(msg) 和 next()是有返回值的,它們的返回值很特殊,返回的是yield表達(dá)式的參數(shù) !

      執(zhí)行順序是:遇到y(tǒng)ield 先返回值,等下次再進(jìn)入時再用 msg 進(jìn)行賦值?。。?/p>

      再來看一個yield的例子,用生成器生成一個Fibonacci數(shù)列:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      def fab(max):
          a, b = 0, 1
          while a < max:
              yield a
              a, b = b, a + b
      for i in fab(20):
          print(i)
      # 0 1 1 2 3 5 8 13

      另一個 yield 的例子來源于文件讀取。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      def read_file(fpath):
         BLOCK_SIZE = 1024
         with open(fpath, 'rb') as f:
             while True:
                 block = f.read(BLOCK_SIZE)
                 if block:
                     yield block
                 else:
                     return

        

      迭代器(iterator)

        for循環(huán)可以用于Python中的任何類型,包括列表、元祖等等,實際上,for循環(huán)可用于任何“可迭代對象”!

        迭代器是一個實現(xiàn)了迭代器協(xié)議的對象,Python中的迭代器協(xié)議就是有next方法的對象會前進(jìn)到下一結(jié)果,而在一系列結(jié)果的末尾是,則會引發(fā)StopIteration。

        任何這類的對象在Python中都可以用for循環(huán)或其他遍歷工具迭代,迭代工具內(nèi)部會在每次迭代時調(diào)用next方法,并且捕捉StopIteration異常來確定何時離開。

        使用迭代器一個顯而易見的好處就是:每次只從對象中讀取一條數(shù)據(jù),不會造成內(nèi)存的過大開銷。

      注意

        判斷迭代器的條件是:

      1. 有__iter__ 方法

      2. 有__next__ 方法

        所有的生成器都是迭代器!

      迭代器例子:

      比如要逐行讀取一個文件的內(nèi)容,利用readlines()方法,我們可以這么寫:

      1
      2
      for line in open("test.txt").readlines():
          print (line)

      這樣雖然可以工作,但不是最好的方法。因為他實際上是把文件一次加載到內(nèi)存中,然后逐行打印。當(dāng)文件很大時,這個方法的內(nèi)存開銷就很大了。

      利用file的迭代器,我們可以這樣寫:

      1
      2
      for line in open("test.txt"):
          print (line)

      這是最簡單也是運行速度最快的寫法,他并沒顯式的讀取文件,而是利用迭代器每次讀取下一行。

      for 循環(huán)實質(zhì)

      1. 調(diào)用 __iter__ 方法將可迭代對象轉(zhuǎn)換成迭代器

      2. 對迭代器對象不斷調(diào)用 __next__ 方法

      3. 處理StopIteration 異常

      View Code

       

      可迭代對象(iterable)

        判斷條件:內(nèi)部具有 __iter__ 方法

      1
      2
      3
      4
      5
      6
      from collections import Iterable,Iterator
      print(isinstance(range(1),Iterable))
      print(isinstance(range(1),Iterator))
      print(isinstance(list(),Iterable))
      print(isinstance(list(),Iterator))

        

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多