python yield使用

yield

最近在學習爬蟲,看的是崔慶才作者的書,看到一個關於爬取貓眼電影排行榜的一個程序,其中這個對於爬取下來的html利用正則表達式進行提取的一個函數中

def parse_one_page(html):  
   pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a' 
+ '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>' 
+ '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)  
    items = re.findall(pattern, html)  
    for item in items:  
        yield {'index': item[0],  
            'image': item[1],  
            'title': item[2],  
            'actor': item[3].strip()[3:],  
            'time': item[4].strip()[5:],  
            'score': item[5] + item[6]  
        }  

我並沒有在這個函數中看到return,but

def main(offset):  
    url = 'http://maoyan.com/board/4?offset=' + str(offset)  
    html = get_one_page(url)  
    for item in parse_one_page(html):  
        print(item)  
        write_to_file(item)

這裏直接在for循環裏調用了parse_one_page,每次都得到了返回值,最後看到了yield,就查了下用法,看到了廖老師12年寫的解析,寫的很清晰,自己也來記錄下,原帖在這
yield的作用就是把一個函數變成一個 generator,!!點這裏看原帖!!

自己理解的yield

就拿上面的parse_one_page來說,在for循環中,每次調用parse_one_page都會得到一個iterable對象,然後賦給item,然後print。
爲什麼呢?
因爲yield 的作用就是把一個函數變成一個 generator,帶有 yield 的函數不再是一個普通函數,Python 解釋器會將其視爲一個 generator,調用 帶有yield的函數 不會執行此函數,而是返回一個 iterable 對象!在 for 循環執行時,每次循環都會執行 函數內部的代碼,執行到 yield 時,函數就返回一個迭代值,下次迭代時,代碼從 yield 的下一條語句繼續執行,而函數的本地變量看起來和上次中斷執行前是完全一樣的,於是函數繼續執行,直到再次遇到 yield。

爲什麼要用yield

如果在parse_one_page中要用return的話,在爬取內容的數量很多的情況下,該函數在運行中佔用的內存太大,因爲字典太大了,而改用了yield之後,每次迭代中都返回一個數值,佔用內存很小,也很簡潔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章