1. 程式人生 > 程式設計 >Python 生成器,迭代,yield關鍵字,send()傳參給yield語句操作示例

Python 生成器,迭代,yield關鍵字,send()傳參給yield語句操作示例

本文例項講述了Python 生成器,迭代,yield關鍵字,send()傳參給yield語句操作。分享給大家供大家參考,具體如下:

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)

執行結果:

0
1
0

demo.py(通過異常判斷迭代是否結束):

def create_num(all_num):
  a,1
  current_num = 0
  while current_num < all_num:
    yield a 
    a,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

執行結果:

0
1
1
2
3
5
8
13
21
34
ok....

demo.py(send()迭代生成器,傳參給yield語句):

def create_num(all_num):
  a,1
  current_num = 0
  while current_num < all_num:
    ret = yield a  # send的引數就是yield語句的返回值。
    print(">>>ret>>>>",ret)  # hahahha
    a,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)

執行結果:

0
>>>ret>>>> hahahha
1

建立生成器的簡單方式:

更多關於Python相關內容可檢視本站專題:《Python資料結構與演算法教程》、《Python Socket程式設計技巧總結》、《Python函式使用技巧總結》、《Python字串操作技巧彙總》及《Python入門與進階經典教程》

希望本文所述對大家Python程式設計有所幫助。