Python基礎篇---生成器和模組
阿新 • • 發佈:2022-03-24
本章內容
• 生成器物件
• 自定義range方法
• yield關鍵字作用
• 生成器表示式
• 模組
生成器物件
生成器物件其本質是自定義迭代器,就是需要我們自己寫程式碼產生的迭代器。
生成器物件也是節省儲存空間的 特性與迭代器物件一致。
def index(): print('第一次輸出') yield 1 print('第二次輸出') yield 2
當我們沒有加括號呼叫之前,它就是一個普通的函式 print(index) # <function index at 0x1096c0ea0> 加括號呼叫並接收結果,不執行程式碼,而是變成生成器物件(迭代器) res = index() # print(res) # <generator object index at 0x11da33468> res有了iter()和next()方法 變成生成器物件之後呼叫__next__就會開始執行函式體程式碼 呼叫一次next: print(res.__next__()) #第一次輸出 1 yield有點像return的功能 停止在這裡 print(res.__next__()) #第二次輸出 2 print(res.__next__()) # 報錯
如果函式體程式碼中含有多個yield關鍵字 執行一次__next__返回後面的值並且讓程式碼停留在yield位置,
再次執行__next__基於上次的位置繼續往後執行到下一個yield關鍵字處,
如果沒有了 再執行也會報錯。
自定義range方法
range方法其實是一個可迭代物件。
需求:通過生成器模擬range方法。
def my_range(): pass for i in my_range(1,10): print(i)
先實現range2個引數的最簡單情況。
def range(start, end): # start為開始 end為結束 whilestart < end: # 設定一個迴圈 去迭代start+1 yield start # 每一次迴圈都返回start start += 1 # 迭代 for i in range(1, 10): print(i)
特殊情況,只有一個引數的情況。
def range(start, end=None): # start為末尾值 end可以不傳值 應該設定成預設引數 if not end: # 沒有給end傳值 end=None 程式碼層面做判斷 將形引數據做替換處理 end = start start= 0 while start < end: # 設定一個迴圈 去迭代x+1 yield start # 每一次迴圈都返回x start += 1 # 迭代 for i in range(1, 10): print(i)
三個引數情況,傳入了步長。
def range(start, end=None,step=1): # 給函式新增第三個形參 並且設定成預設引數 預設值是1 step=1 if not end: # 沒有給end傳值 end=None 程式碼層面做判斷 將形引數據做替換處理 end = start start = 0 while start < end: # 設定一個迴圈 去迭代x+1 yield start # 每一次迴圈都返回x start += step # 每次遞增的時候只需要遞增step的數值即可 for i in range(1, 10): print(i)
寫程式碼一定不要想太多,先搭建主題功能,之後再考慮其他情況,思路一定要清晰!!!
yield的作用: 在函式體程式碼中出現 可以將函式變成生成器 在執行過程中 可以將後面的值返回出去 類似於return 還可以暫停住程式碼的執行 還可以接收外界的傳值(瞭解)
def go_home(name): print(f'{name}在回家路上') while True: home= yield print(f'{name}到家了{home}') res = go_home('jason') # 想執行一次程式碼 如果想執行多次直至結束 可以直接用for迴圈 res.__next__() res.__next__() # 給yield傳值 res.send('沒有鑰匙') # 可以給yield傳值 並且自動呼叫一次__next__方法 res.send('有鑰匙') # 可以給yield傳值 並且自動呼叫一次__next__方法
生成器表示式也是為了節省儲存空間,用來做程式碼優化,前期學習可以忽略。
# 生成器表示式 res = (i for i in 'jason') print(res) # <generator object <genexpr> at 0x0000022C8D360D00> print(res.__next__()) # j print(res.__next__()) # a print(res.__next__()) # s """生成器內部的程式碼只有在呼叫__next__迭代取值的時候才會執行"""
下面有一個生成器表示式的例題,訣竅在於生成器的呼叫。
# 普通的求和函式 def add(n, i): return n + i # 生成器物件 返回 0 1 2 3 def test(): for i in range(4): yield i # 將test函式變成生成器物件 g = test() # 簡單的for迴圈 for n in [1, 10]: g = (add(n, i) for i in g) """ 第一次for迴圈 g = (add(n, i) for i in g) 第二次for迴圈 g = (add(10, i) for i in (add(10, i) for i in g)) """ res = list(g) # list底層就是for迴圈 相當於對g做了迭代取值操作 print(res) #A. res=[10,11,12,13] #B. res=[11,12,13,14] #C. res=[20,21,22,23] #D. res=[21,22,23,24] """正確答案是C 訣竅就是抓n是多少即可"""
模組
簡介
模組就是一系列功能的結合體,可以直接使用,極大地提升開發效率。
模組的三種來源
內建的模組 無需下載 直譯器自帶 直接匯入使用即可 自定義模組 自己寫的程式碼 封裝成模組 自己用或者釋出到網上供別人使用 第三方模組 別人寫的釋出到網上的 可以下載使用的模組(很多牛逼的模組都是第三方)
模組的四種表現形式
使用python程式碼編寫的py檔案 # 掌握 多個py檔案組成的資料夾(包) # 掌握 已被編譯為共享庫或DLL的c或C++擴充套件(瞭解) 使用C編寫並連結到python直譯器的內建模組(瞭解)
要想使用模組,必須先把模組匯入,而匯入的方法有兩種。
方式1>>>:import...句式