Python 生成器,迭代,yield關鍵字,send()傳參給yield語句
阿新 • • 發佈:2018-12-07
demo.py(生成器,yield關鍵字):
# 生成器是一個特殊的迭代器。可以用for...in遍歷。 # 帶有yield關鍵字的函式,不再是一個函式,而是一個生成器模板。呼叫該模板會返回一個生成器物件。 def create_num(all_num): a, b = 0, 1 current_num = 0 while current_num < all_num: yield a # 當遍歷create_num返回的生成器時,會阻塞在yield的位置。每次遍歷出的值都是yield後的值。 a, b = b, a+b current_num += 1 # return '返回值' # 迭代結束後,繼續呼叫next會拋StopIteration異常。 可以通過該異常來獲取該返回值。 (異常.value 就是該返回值) # create_num"函式"中有一個yield,那麼create_num不再是一個函式。呼叫時,會返回一個生成器物件。 obj = create_num(10) # 只會返回一個生成器物件(可用於遍歷)。並不會執行create_num中的程式碼,只有遍歷(迭代)時才會執行create_num中的程式碼。 ret = next(obj) # 迭代的本質就是呼叫物件的__next__函式。 會返回yield後面的值,並阻塞程式碼,直到再次呼叫next(或迭代)才會解阻塞。 print(ret) # 當create_num中的程式碼執行完後,迭代就會結束。 ret = next(obj) # 如果迭代結束後,繼續呼叫next,那麼會拋異常。 可以通過異常來獲取create_num return的值。 print(ret) # 可以通過異常來判斷是否迭代結束。 obj2 = create_num(2) # obj2和obj的遍歷迭代互不影響。 ret = next(obj2) print(ret) # for num in obj: # print(num)
demo.py(通過異常判斷迭代是否結束):
def create_num(all_num): a, b = 0, 1 current_num = 0 while current_num < all_num: yield a a, b = b, a+b current_num += 1 return "ok...." # 通過迭代結束後的異常來獲取該返回值 obj = create_num(10) # 返回一個生成器物件。並不會執行create_num中的程式碼,只有遍歷迭代obj時才會執行create_num中的程式碼 while True: try: ret = next(obj) # 迭代結束後繼續呼叫next會拋異常。 print(ret) except Exception as ret: print(ret.value) # 通過異常獲取create_num return的值。 break
demo.py(send()迭代生成器,傳參給yield語句):
def create_num(all_num): a, b = 0, 1 current_num = 0 while current_num < all_num: ret = yield a # send的引數就是yield語句的返回值。 print(">>>ret>>>>", ret) # hahahha a, b = b, a+b current_num += 1 obj = create_num(10) # obj.send(None) # send一般不會放到第一次啟動(迭代)生成器,如果非要這樣做 那麼傳遞None (否則會拋異常) ret = next(obj) # 第一次遍歷迭代生成器時,建議使用next函式。 print(ret) # send與next作用相同,都是進行下一次迭代的意思。 (都會解阻塞yield關鍵字) # send可以傳遞引數表示yield語句的返回值。 而next不能傳遞引數。 ret = obj.send("hahahha") # 會先將"hahahha"引數當做yield語句的返回值,然後再解阻塞yield 遍歷。(因此不推薦第一次遍歷時使用send傳參) print(ret)
建立生成器的簡單方式: