8多任務(wù)3: 協(xié)程及應(yīng)用:圖片下載器

一、總體內(nèi)容

1.1虫给、協(xié)程的介紹

1.2藤抡、迭代器以及迭代器的應(yīng)用

1.3、生成器(生成器與迭代器保存的都是生成數(shù)據(jù)的代碼抹估,而不是數(shù)據(jù))

1.4缠黍、gevent 來實現(xiàn)一個?圖片下載器?&?視頻下載器

二、協(xié)程介紹

2.1药蜻、協(xié)程是什么瓷式?

協(xié)程,又稱微線程语泽,纖程贸典。英文名Coroutine:英[k?ru:'ti:n]。

協(xié)程是python個中另外一種實現(xiàn)多任務(wù)的方式湿弦,只不過比線程更小占用更小執(zhí)行單元(理解為需要的資源)瓤漏。 為啥說它是一個執(zhí)行單元,因為它自帶CPU上下文颊埃。這樣只要在合適的時機蔬充, 我們可以把一個協(xié)程 切換到另一個協(xié)程。 只要這個過程中保存或恢復 CPU上下文那么程序還是可以運行的班利。

通俗的理解:在一個線程中的某個函數(shù)饥漫,可以在任何地方保存當前函數(shù)的一些臨時變量等信息,然后切換到另外一個函數(shù)中執(zhí)行罗标,注意不是通過調(diào)用函數(shù)的方式做到的庸队,并且切換的次數(shù)以及什么時候再切換到原來的函數(shù)都由開發(fā)者自己確定积蜻。

2.2、協(xié)程和線程差異

在實現(xiàn)多任務(wù)時, 線程切換從系統(tǒng)層面遠不止保存和恢復 CPU上下文這么簡單彻消。 操作系統(tǒng)為了程序運行的高效性每個線程都有自己緩存Cache等等數(shù)據(jù)竿拆,操作系統(tǒng)還會幫你做這些數(shù)據(jù)的恢復操作。 所以線程的切換非常耗性能宾尚。但是協(xié)程的切換只是單純的操作CPU的上下文丙笋,所以一秒鐘切換個上百萬次系統(tǒng)都抗的住。

2.3煌贴、簡單實現(xiàn)協(xié)程(暫時用yield,后面我們主要用?gevent?來實現(xiàn)?協(xié)程)

import time

def work1():

? ? ? while True:

? ? ? ? ? print("----work1---")

? ? ? ? ? yield

? ? ? ? ? time.sleep(0.5)

def work2():

? ? ? while True:

? ? ? ? ? print("----work2---")

? ? ? ? ? yield

? ? ? ? ? time.sleep(0.5)

def main():

? ? ? w1 = work1()

? ? ? w2 = work2()

? ? ? while True:

? ? ? ? ? next(w1)

? ? ? ? ? next(w2)

if __name__ == "__main__":

? ? ? main()

運行結(jié)果:

---work1---

----work2---

----work1---

----work2---

----work1---

----work2---

---------等等-------

三御板、迭代器

3.1、迭代器的介紹

迭代是訪問集合元素的一種方式牛郑。迭代器是一個可以記住遍歷的位置的對象怠肋。迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結(jié)束淹朋。迭代器只能往前不會后退笙各。

3.2、可迭代對象

我們已經(jīng)知道可以對list础芍、tuple酪惭、str等類型的數(shù)據(jù)使用for...in...的循環(huán)語法從其中依次拿到數(shù)據(jù)進行使用,我們把這樣的過程稱為遍歷者甲,也叫迭代。是否所有的數(shù)據(jù)類型都可以放到for...in...的語句中砌创,然后讓for...in...每次從中取出一條數(shù)據(jù)供我們使用虏缸,即供我們迭代嗎?

打印結(jié)果是:從下面可以看出不可迭代

TypeError:'MyList'objectisnot iterable

我們自定義了一個容器類型MyList嫩实,在將一個存放了多個數(shù)據(jù)的MyList對象放到for...in...的語句中刽辙,發(fā)現(xiàn)for...in...并不能從中依次取出一條數(shù)據(jù)返回給我們,也就說我們隨便封裝了一個可以存放多條數(shù)據(jù)的類型卻并不能被迭代使用甲献。

我們把可以通過for...in...這類語句迭代讀取一條數(shù)據(jù)供我們使用的對象稱之為可迭代對象(Iterable)宰缤。

3.3、如何判斷一個對象是否可以迭代

可以使用?isinstance()判斷一個對象是否是?Iterable對象,如下判斷

3.4晃洒、可迭代對象的本質(zhì)

我們分析對可迭代對象進行迭代使用的過程慨灭,發(fā)現(xiàn)每迭代一次(即在for...in...中每循環(huán)一次)都會返回對象中的下一條數(shù)據(jù),一直向后讀取數(shù)據(jù)直到迭代了所有數(shù)據(jù)后結(jié)束球及。那么氧骤,在這個過程中就應(yīng)該有一個“人”去記錄每次訪問到了第幾條數(shù)據(jù),以便每次迭代都可以返回下一條數(shù)據(jù)吃引。我們把這個能幫助我們進行數(shù)據(jù)迭代的“人”稱為迭代器(Iterator:[?t?'re?t?])筹陵。

可迭代對象的本質(zhì) 就是可以向我們提供一個這樣的中間“人”即迭代器幫助我們對其進行迭代遍歷使用刽锤。

可迭代對象通過iter方法向我們提供一個迭代器,我們在迭代一個可迭代對象的時候朦佩,實際上就是先獲取該對象提供的一個迭代器并思,然后通過這個迭代器來依次獲取對象中的每一個數(shù)據(jù).

那么也就是說,一個具備了__iter__方法的對象语稠,就是一個可迭代對象宋彼。

在一個類里面加上 __iter__就可以使這個類成為可迭代的對象

打印結(jié)果是:True, 這回測試發(fā)現(xiàn)添加了__iter__方法的mylist對象已經(jīng)是一個?可迭代對象?了

3.5、 iter()函數(shù)與next()函數(shù)

list颅筋、tuple等都是可迭代對象宙暇,我們可以通過iter()函數(shù)獲取這些可迭代對象的迭代器。然后我們可以對獲取到的迭代器不斷使用next()函數(shù)來獲取下一條數(shù)據(jù)议泵。iter()函數(shù)實際上就是調(diào)用了可迭代對象的__iter__方法占贫。

注意,當我們已經(jīng)迭代完最后一個數(shù)據(jù)之后先口,再次調(diào)用next()函數(shù)會拋出StopIteration的異常型奥,來告訴我們所有數(shù)據(jù)都已迭代完成,不用再執(zhí)行next()函數(shù)了碉京。

3.6厢汹、如何判斷一個對象是否是迭代器

可以使用 isinstance() 判斷一個對象是否是 Iterator 對象:

3.7、迭代器Iterator

通過上面的分析谐宙,我們已經(jī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__方法返回自身即可。

from collections import Iterator

from collections import Iterable

class MyList(object):

? ? ? def __init__(self):

? ? ? ? ? self.name_list = []

? ? ? ? ? self.all_count = 0

? ? ? def add_name(self,temp):

? ? ? ? ? self.name_list.append(temp)

? ? ? def __iter__(self):

? ? ? ? ? return self

? ? ? def __next__(self):

? ? ? ? ? ? if self.all_count < len(self.name_list):

? ? ? ? ? ? ? ? ? ? ret = self.name_list[self.all_count]

? ? ? ? ? ? ? ? ? ? self.all_count += 1

? ? ? ? ? ? ? ? ? ? return ret

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? ? ? raise StopIteration

my_list = MyList()

my_list.add_name("張三")

my_list.add_name("李四")

my_list.add_name("王五")

print("判斷my_list是否是可以迭代的對象:",isinstance(my_list,Iterable))

my_list_iterator = iter(my_list)

print("判斷my_list_iterator是否是迭代器:",isinstance(my_list_iterator,Iterator))

for name in my_list:

? ? ? print(name)


提示:一個實現(xiàn)了__iter__方法和__next__方法的對象头遭,就是迭代器寓免。

3.8癣诱、for...in...循環(huán)的本質(zhì)

for item in Iterable 循環(huán)的本質(zhì)就是先通過iter()函數(shù)獲取可迭代對象Iterable的迭代器,然后對獲取到的迭代器不斷調(diào)用next()方法來獲取下一個值并將其賦值給item袜香,當遇到StopIteration的異常后循環(huán)結(jié)束撕予。

3.9、迭代器的應(yīng)用場景

我們發(fā)現(xiàn)迭代器最核心的功能就是可以通過next()函數(shù)的調(diào)用來返回下一個數(shù)據(jù)值蜈首。如果每次返回的數(shù)據(jù)值不是在一個已有的數(shù)據(jù)集合中讀取的实抡,而是通過程序按照一定的規(guī)律計算生成的,那么也就意味著可以不用再依賴一個已有的數(shù)據(jù)集合欢策,也就是說不用再將所有要迭代的數(shù)據(jù)都一次性緩存下來供后續(xù)依次讀取吆寨,這樣可以節(jié)省大量的存儲(內(nèi)存)空間

舉例:比如踩寇,數(shù)學中有個著名的斐波拉契數(shù)列(Fibonacci)啄清,數(shù)列中第一個數(shù)為0,第二個數(shù)為1俺孙,其后的每一個數(shù)都可由前兩個數(shù)相加得到:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

class FibIterator(object):

? ? ? ? """斐波那契數(shù)列迭代器"""

? ? ? def __init__(self,num):

? ? ? ? ? ? """

? ? ? ? ? ? :param num: 指明生成數(shù)列的前num個數(shù)

? ? ? ? ? ? """

? ? ? ? ? ? self.all_num = num

? ? ? ? ? ? # 用來保存當前生成到數(shù)列中的第幾個數(shù)了

? ? ? ? ? ? self.num = 0

? ? ? ? ? ? # 用來保存前前一個數(shù)辣卒,初始值為數(shù)列中的第一個數(shù)0

? ? ? ? ? ? self.start_a = 0

? ? ? ? ? ? # 用來保存前后一個數(shù),初始值為數(shù)列中的第二個數(shù)1

? ? ? ? ? ? self.start_b = 1

? ? ? def __iter__(self):

? ? ? ? ? ? # """迭代器的__iter__返回自身即可"""

? ? ? ? ? ? return self

? ? ? def __next__(self):

? ? ? ? ? ? # """被next()函數(shù)調(diào)用來獲取下一個數(shù)"""

? ? ? ? ? ? if self.num < self.all_num:

? ? ? ? ? ? ? ? ? self.num += 1

? ? ? ? ? ? ? ? ? retValue = self.start_a

? ? ? ? ? ? ? ? ? self.start_a,self.start_b = self.start_b,self.start_a+self.start_b

? ? ? ? ? ? ? ? ? return self.start_a

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? ? raise StopIteration

fibIterator = FibIterator(20)

for num in fibIterator:

? ? ? ? print(num)

3.10睛榄、并不是只有for循環(huán)能接收可迭代對象

除了for循環(huán)能接收可迭代對象荣茫,list、tuple等也能接收场靴。


3.11啡莉、以后再見到?元組轉(zhuǎn)列表列表轉(zhuǎn)元組旨剥,不要再認為是簡簡單單的轉(zhuǎn)換了票罐;比如下面的例子

四、生成器

4.1泞边、生成器介紹

利用迭代器,我們可以在每次迭代獲取數(shù)據(jù)(通過next()方法)時按照特定的規(guī)律進行生成疗杉。但是我們在實現(xiàn)一個迭代器時阵谚,關(guān)于當前迭代到的狀態(tài)需要我們自己記錄,進而才能根據(jù)當前狀態(tài)生成下一個數(shù)據(jù)烟具。為了達到記錄當前狀態(tài)梢什,并配合next()函數(shù)進行迭代使用,我們可以采用更簡便的語法朝聋,即生成器(generator)嗡午。生成器是一類特殊的迭代器

4.2冀痕、創(chuàng)建生成器方法

創(chuàng)建生成器方法1

創(chuàng)建 L 和 G 的區(qū)別僅在于最外層的 [ ] 和 ( ) 荔睹, L 是一個列表狸演,而 G 是一個生成器。我們可以直接打印出列表L的每一個元素僻他,而對于生成器G宵距,我們可以按照迭代器的使用方法來使用,即可以通過next()函數(shù)吨拗、for循環(huán)满哪、list()等方法使用

創(chuàng)建生成器方法2

generator非常強大。如果推算的算法比較復雜劝篷,用類似列表生成式的for循環(huán)無法實現(xiàn)的時候哨鸭,還可以用函數(shù)來實現(xiàn)。我們?nèi)匀挥枚刑岬降?b>斐波那契數(shù)列來舉例娇妓,回想我們在上一節(jié)用迭代器的實現(xiàn)方式:

在使用生成器實現(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ù)體了蕊蝗,而是會返回一個生成器對象( 案例中為F )仅乓,然后就可以按照使用迭代器的方式來使用生成器了。

但是用for循環(huán)調(diào)用generator時蓬戚,發(fā)現(xiàn)拿不到generator的return語句的返回值夸楣。如果想要拿到返回值,必須捕獲StopIteration錯誤子漩,返回值包含在StopIteration的value中:

總結(jié)

使用了yield關(guān)鍵字的函數(shù)不再是函數(shù)豫喧,而是生成器。(使用了yield的函數(shù)就是生成器)

yield關(guān)鍵字有兩點作用:

保存當前運行狀態(tài)(斷點)幢泼,然后暫停執(zhí)行紧显,即將生成器(函數(shù))掛起

將yield關(guān)鍵字后面表達式的值作為返回值返回,此時可以理解為起到了return的作用

可以使用next()函數(shù)讓生成器從斷點處繼續(xù)執(zhí)行缕棵,即喚醒生成器(函數(shù))

Python3中的生成器可以使用return返回最終運行的返回值孵班,而Python2中的生成器不允許使用return返回一個返回值(即可以使用return從生成器中退出,但return后不能有任何表達式)招驴。

4.3篙程、使用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)

4.4、使用__next__()方法(不常使用)

4.5折柠、greenlet

為了更好使用協(xié)程來完成多任務(wù)宾娜,python中的greenlet模塊對其封裝,從而使得切換任務(wù)變的更加簡單

安裝方式

sudo pip3 install greenlet

使用方式


4.6扇售、gevent (重點)

其原理是當一個greenlet遇到IO(指的是input output 輸入輸出前塔,比如網(wǎng)絡(luò)、文件操作等)操作時承冰,比如訪問網(wǎng)絡(luò)华弓,就自動切換到其他的greenlet,等到IO操作完成困乒,再在適當?shù)臅r候切換回來繼續(xù)執(zhí)行寂屏。

由于IO操作非常耗時,經(jīng)常使程序處于等待狀態(tài)娜搂,有了gevent為我們自動切換協(xié)程迁霎,就保證總有g(shù)reenlet在運行,而不是等待IO

安裝 gevent

pip3 install gevent

gevent的使用

運行結(jié)果(可以看到百宇,3個gevent是依次運行而不是交替運行)

gevent切換執(zhí)行

運行結(jié)果: 可以看到是交替執(zhí)行的??

.7考廉、給程序打補丁(如果你在使用gevent的模塊中sleep()用的是time模塊,那么為了使gevent也起作用携御,那么就要進行打補恫痢)

需要加上下面的代碼

# 有耗時操作時需要

monkey.patch_all()? # 將程序中用到的耗時操作的代碼,換為gevent中自己實現(xiàn)的模塊

完整的代碼如下

運行結(jié)果如下:


五啄刹、gevent 來實現(xiàn)一個圖片下載器

5.1涮坐、我們在下載網(wǎng)絡(luò)的時候會用到urllib.request,在用到打開一個鏈接urllib.request.urlopen的時候會報錯:urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)>,這是我的報錯

原因是:查找相關(guān)資料后確定為Python 2.7.9 之后版本引入了一個新特性

當你urllib.urlopen一個 https 的時候會驗證一次 SSL 證書

當目標使用的是自簽名的證書時就會爆出一個上面的錯誤,

處理辦法如下:在全局添加下面代碼

importssl ssl._create_default_https_context=ssl._create_unverified_context

作者:IIronMan

鏈接:http://www.reibang.com/p/dabef6d19aed

來源:簡書

著作權(quán)歸作者所有誓军。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)袱讹,非商業(yè)轉(zhuǎn)載請注明出處。

5.2昵时、使用協(xié)程 gevent 實現(xiàn)的圖片下載器

import urllib.request

import ssl

from gevent import monkey

import gevent

monkey.patch_all()

ssl._create_default_https_context = ssl._create_unverified_context

def down_loader_image(image_name,image_url):

? ? ? ? """

? ? ? ? 使用進程 gevent的圖片下載器

? ? ? ? :param image_name: 圖片的名字

? ? ? ? :param image_url: 圖片的url

? ? ? ? """

? ? ? ? req = urllib.request.urlopen(image_url)

? ? ? ? image_content = req.read()

? ? ? ? with open("/Users/wangchong/Desktop/%s"%image_name,"wb") as f:

? ? ? ? ? ? ? f.write(image_content)

def main():

? ? gevent.joinall([

? ? ? ? ? ? ? gevent.spawn(down_loader_image,"20.png","https://rpic.douyucdn.cn/live-cover/appCovers/2018/11/15/5658062_20181115170406_small.jpg"),

? ? ? ? ? ? ? gevent.spawn(down_loader_image,"21.png","https://rpic.douyucdn.cn/live-cover/roomCover/2018/09/27/b0983e7b6267f5b8371106ccf5f113ab_big.jpg")

? ? ? ])

if __name__ == '__main__':

5.3廓译、使用協(xié)程 gevent 實現(xiàn)多個視頻下載

import urllib.request

import ssl

from gevent import monkey

import gevent

#有IO才做時需要這一句,將程序中用到的耗時操作的代碼,換為gevent中自己實現(xiàn)的模塊

monkey.patch_all()

ssl._create_default_https_context = ssl._create_unverified_context

def down_loader_image(video_name,video_url):

? ? ? ? """

? ? ? ? 使用進程 gevent的圖片下載器

? ? ? ? :param video_name: 視頻的名字

? ? ? ? :param video_url: 圖片的url

? ? ? ? """

? ? ? ? req = urllib.request.urlopen(video_url)

? ? ? ? data = req.read()

? ? ? ? with open("/Users/wangchong/Desktop/%s"% video_name,"wb") as f:

? ? ? ? ? ? ? f.write(data)

? ? ? ? print('%d bytes received from %s.' % (len(data), video_url))

def main():

? ? gevent.joinall([

? ? ? ? ? ? ? gevent.spawn(down_loader_image,"1.mp4","http://images.ciotimes.com/2.wx_test.mp4"),

? ? ? ? ? ? ? gevent.spawn(down_loader_image,"2.mp4","http://images.ciotimes.com/3.wx_test.mp4")

? ? ? ])

if __name__ == '__main__':

? ? ? main()

提示 上面的url可以換為自己需要下載視頻债查、音樂、圖片等網(wǎng)址

六瓜挽、總結(jié):進程盹廷、線程、協(xié)程對比

6.1久橙、對進程俄占、線程管怠、協(xié)程三者的描述

有一個老板想要開個工廠進行生產(chǎn)某件商品(例如剪子)

他需要花一些財力物力制作一條生產(chǎn)線,這個生產(chǎn)線上有很多的器件以及材料這些所有的 為了能夠生產(chǎn)剪子而準備的資源稱之為:進程

只有生產(chǎn)線是不能夠進行生產(chǎn)的缸榄,所以老板的找個工人來進行生產(chǎn)渤弛,這個工人能夠利用這些材料最終一步步的將剪子做出來,這個來做事情的工人稱之為:線程

這個老板為了提高生產(chǎn)率甚带,想到3種辦法:

在這條生產(chǎn)線上多招些工人她肯,一起來做剪子,這樣效率是成倍増長鹰贵,即單進程 多線程方式

老板發(fā)現(xiàn)這條生產(chǎn)線上的工人不是越多越好晴氨,因為一條生產(chǎn)線的資源以及材料畢竟有限,所以老板又花了些財力物力購置了另外一條生產(chǎn)線碉输,然后再招些工人這樣效率又再一步提高了籽前,即多進程 多線程方式

老板發(fā)現(xiàn),現(xiàn)在已經(jīng)有了很多條生產(chǎn)線敷钾,并且每條生產(chǎn)線上已經(jīng)有很多工人了(即程序是多進程的枝哄,每個進程中又有多個線程),為了再次提高效率阻荒,老板想了個損招挠锥,規(guī)定:如果某個員工在上班時臨時沒事或者再等待某些條件(比如等待另一個工人生產(chǎn)完謀道工序 之后他才能再次工作) ,那么這個員工就利用這個時間去做其它的事情财松,那么也就是說:如果一個線程等待某些條件瘪贱,可以充分利用這個時間去做其它事情,其實這就是:協(xié)程方式

6.2辆毡、總體描述

進程是資源分配的單位

線程是操作系統(tǒng)調(diào)度的單位

進程切換需要的資源很最大菜秦,效率很低

線程切換需要的資源一般,效率一般(當然了在不考慮GIL的情況下)

協(xié)程切換任務(wù)資源很小舶掖,效率高

多進程球昨、多線程根據(jù)cpu核數(shù)不一樣可能是并行的,但是協(xié)程是在一個線程中 所以是并發(fā)

協(xié)程依賴于線程眨攘,線程依賴于進程主慰,進程一死,協(xié)程必掛


作者:IIronMan

鏈接:http://www.reibang.com/p/dabef6d19aed

來源:簡書

著作權(quán)歸作者所有鲫售。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)共螺,非商業(yè)轉(zhuǎn)載請注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末情竹,一起剝皮案震驚了整個濱河市藐不,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖雏蛮,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涎嚼,死亡現(xiàn)場離奇詭異,居然都是意外死亡挑秉,警方通過查閱死者的電腦和手機法梯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來犀概,“玉大人立哑,你說我怎么就攤上這事≮逡保” “怎么了刁憋?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長木蹬。 經(jīng)常有香客問我至耻,道長,這世上最難降的妖魔是什么镊叁? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任尘颓,我火速辦了婚禮,結(jié)果婚禮上晦譬,老公的妹妹穿的比我還像新娘疤苹。我一直安慰自己,他們只是感情好敛腌,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布卧土。 她就那樣靜靜地躺著,像睡著了一般像樊。 火紅的嫁衣襯著肌膚如雪尤莺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天生棍,我揣著相機與錄音颤霎,去河邊找鬼。 笑死涂滴,一個胖子當著我的面吹牛友酱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播柔纵,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼缔杉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了搁料?” 一聲冷哼從身側(cè)響起或详,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤进苍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鸭叙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡拣宏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年沈贝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勋乾。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡宋下,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辑莫,到底是詐尸還是另有隱情学歧,我是刑警寧澤系奉,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布圈盔,位于F島的核電站晒骇,受9級特大地震影響嗜侮,放射性物質(zhì)發(fā)生泄漏鸳粉。R本人自食惡果不足惜彪见,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一萌腿、第九天 我趴在偏房一處隱蔽的房頂上張望腻暮。 院中可真熱鬧屉更,春花似錦徙融、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至萨脑,卻和暖如春隐轩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背砚哗。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工龙助, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛛芥。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓提鸟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仅淑。 傳聞我的和親對象是個殘疾皇子称勋,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 一、總體內(nèi)容 1.1涯竟、協(xié)程的介紹 1.2赡鲜、迭代器以及迭代器的應(yīng)用 1.3空厌、生成器(生成器與迭代器保存的都是生成數(shù)據(jù)...
    IIronMan閱讀 861評論 0 1
  • 迭代、迭代器银酬、生成器嘲更、協(xié)程、yield揩瞪、greenlet赋朦、gevent、進程線程協(xié)程對比李破、gevent多任務(wù)圖片下...
    Cestine閱讀 482評論 0 0
  • 本節(jié)課綱 可迭代對象 迭代器 生成器Python中內(nèi)置的序列嗤攻,如list毛嫉、tuple、str妇菱、bytes承粤、dict...
    郭_揚閱讀 1,203評論 0 0
  • 系統(tǒng)編程:多任務(wù)編程 1. 線程: 可以理解成執(zhí)行代碼的分支,線程是執(zhí)行對應(yīng)的代碼的 1.1 線程的工作原理: ...
    夢醒家先生閱讀 972評論 2 0
  • 一直都聽很多人說要學會好好愛自己恶耽,但是沒有人具體來說怎么去好好愛自己密任,愛自己到底要做什么 昨天跟男朋友聊天,聊...
    小蝸牛x閱讀 284評論 0 0