1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Python高級特性之迭代器、生成器、裝飾器和上下文管理器

        共 2417字,需瀏覽 5分鐘

         ·

        2021-09-14 23:21

        今天測試Python高級特性-迭代器、生成器、裝飾器、上下文管理器。高級語言特性可以使得程序更加Pythonic,可讀性、可維護(hù)性顯著增加。下面四個(gè)高級特性,筆者在收集資料以及用ipython測試。裝飾器的只是測試基本的功能,筆者覺得有點(diǎn)復(fù)雜。


        1、迭代器

         迭代器協(xié)議是指:對象需要提供next方法,要么返回迭代中的下一項(xiàng),要么就引起一個(gè)StopIteration異常以終止迭代,防止出現(xiàn)無限循環(huán)的情況。迭代器是一個(gè)可以記住遍歷的位置的對象。


        迭代器有兩個(gè)基本的方法:iter() 和 next()字符串,列表或元組對象都可用于創(chuàng)建迭代器:

        迭代器對象可以使用常規(guī)for語句(使用迭代器協(xié)議訪問對象)進(jìn)行遍歷:

        文件對象在python中實(shí)現(xiàn)了迭代器協(xié)議,有next方法,可以很方便的訪問文件中的內(nèi)容。

        也可以自己創(chuàng)建一個(gè)迭代器,下面時(shí)筆者根據(jù)資料來創(chuàng)建的一個(gè)打印20位數(shù)值的迭代器。把類作為一個(gè)迭代器使用需要在類中實(shí)現(xiàn)兩個(gè)方法 __iter__()__next__() 。


        __iter__() 方法返回一個(gè)特殊的迭代器對象,在 __next__() 方法中我們可以設(shè)置在完成指定循環(huán)次數(shù)后觸發(fā) StopIteration 異常來結(jié)束迭代。


        2、生成器       

        生成器自動(dòng)實(shí)現(xiàn)了迭代器協(xié)議。使用了 yield 的函數(shù)被稱為生成器,跟普通函數(shù)不同的是,生成器是一個(gè)返回迭代器的函數(shù)。在調(diào)用生成器運(yùn)行的過程中,每次遇到 yield 時(shí)函數(shù)會暫停并保存當(dāng)前所有的運(yùn)行信息,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時(shí)從當(dāng)前位置繼續(xù)運(yùn)行。調(diào)用一個(gè)生成器函數(shù),返回的是一個(gè)迭代器對象。


        python有兩種方法來提供生成器。


        2.1 生成器函數(shù)

        使用yield 語句而不是return返回結(jié)果。函數(shù)就是一個(gè)實(shí)現(xiàn)了迭代器協(xié)議的函數(shù),可以直接使用for來遍歷。


        2.2 生成器表達(dá)式

        將列表推導(dǎo)中的中括號換成圓括號就是生成器表達(dá)式。squares_list是個(gè)列表推導(dǎo),返回的是個(gè)列表。squares使用生成器表達(dá)式,返回的是個(gè)生成器對象generator object ,由于生成器自動(dòng)實(shí)現(xiàn)了迭代器協(xié)議,使用for循環(huán)迭代輸出。

        生成器可以延遲計(jì)算,一次返回一個(gè)結(jié)果,而不是一次返回使用結(jié)果,對于大數(shù)據(jù)量處理十分有用。


        3、裝飾器

        裝飾器本質(zhì)上是個(gè)函數(shù),這個(gè)函數(shù)接收其他函數(shù)作為參數(shù)。下面是定義bread裝飾器修改say_hi函數(shù)的功能,即使用bread函數(shù)來封裝say_hi函數(shù),@是裝飾器語法,bread是裝飾器的名稱。

        在實(shí)際應(yīng)用中,可以將重復(fù)的代碼提煉出來作為一個(gè)單獨(dú)的函數(shù),然后做成裝飾器,可以提高代碼的可讀性,代碼量也會更少,也降低后期維護(hù)代價(jià)。下面是定義的計(jì)算函數(shù)計(jì)算時(shí)間的benchmark裝飾器,然后在加法和減法函數(shù)里面使用benchmark裝飾器來封裝。

        但是裝飾器的語法較復(fù)雜,執(zhí)行速度也較慢和難以調(diào)試。


        4、上下文管理器

        with 上下文管理器的作用與try/finally語句作用類似,在確保打開的資源在任何情況下都能關(guān)閉。在python在python中優(yōu)先使用上下文管理器,可以用更少的代碼完成相同的功能,而且邏輯更加清除。


        with語句的表達(dá)式返回一個(gè)對象,該對象必須有__enter__和__exit__方法。上面的第一部分打開文件后文件對象在python中實(shí)現(xiàn)了迭代器協(xié)議,有next方法,也有__enter____exit__方法,可以使用 with 上下文管理器:with open('data.csv') as f 。

        上下文管理器可以以一種更加優(yōu)雅的方式,操作(創(chuàng)建/獲取/釋放)資源,如文件操作、數(shù)據(jù)庫連接,并且處理異常。下面是自己定義上下文管理器,含有__enter____exit__方法的對象Resource。

        在上面吃的例子中,寫了一個(gè)類來構(gòu)建上下文管理器。可以使用contextlib 來簡化上下文管理器的邏輯,其提供了contextmanager的裝飾器,通過該裝飾器裝飾的函數(shù)就成為一個(gè)上下文管理器,可以用在with語句中。


        在被裝飾函數(shù)里,必須是一個(gè)生成器(帶有yield),而yield之前的代碼,就相當(dāng)于__enter__里的內(nèi)容。yield 之后的代碼,就相當(dāng)于__exit__ 里的內(nèi)容。下面是自己來定義一個(gè)open_func函數(shù),使用contextmanager來裝飾成上下文管理器,yield之前的代碼時(shí)打開文件,yield之后的代碼是關(guān)閉文件。

        上面這段代碼只能實(shí)現(xiàn)上下文管理器的第一個(gè)目的(管理資源),并不能實(shí)現(xiàn)第二個(gè)目的(處理異常)??梢允褂胻ry + except+finally來實(shí)現(xiàn)異常處理。

        在實(shí)際中,可能不需要except來拋出異常,只是用try + finally。下面是以前做過的將連接數(shù)據(jù)庫的功能使用contextmanager來裝飾成上下文管理器。

        在上下文管理器中,with語句可以使用逗號隔開,同時(shí)使用多個(gè)上下文管理器。


        作者:劉小白DOER
        鏈接:https://www.jianshu.com/p/211276cbfd9d
        來源:簡書


        - EOF -


        回復(fù)關(guān)鍵字“簡明python ”,立即獲取入門必備書籍簡明python教程》電子版

        回復(fù)關(guān)鍵字爬蟲”,立即獲取爬蟲學(xué)習(xí)資料

        點(diǎn)擊關(guān)注【python入門與進(jìn)階】,閱讀更多精彩內(nèi)容
        ??????

        推薦

        瀏覽 74
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            大香蕉在线成人 | 性小视频 | 日本亚洲欧洲免费 | 秋霞日韩在线 | 五月天婷婷在线视频 | 性欧美激情aa在线看 | 国产主播99 | 成人黄网站免费观看 | 9l蝌蚪PORNY中文自拍 | 国产视频黄在线观看 |