協程函數python
面向過程編程shell
遞歸與二分法編程
內置函數 lambdaapp
模塊與包的使用函數
importspa
from ... import ...設計
經常使用模塊code
##################################協程
函數中只要有yield , 函數執行的結果就變成了一個生成器blog
他並不會立刻執行
生成器自己就是一個迭代器,使用next() 觸發函數的執行
yield功能
一、把函數的執行結果封裝好__iter__和__next__,獲得一個迭代器
二、與return功能相似,均可以返回值,但不一樣的是,return只能返回一次值,而yield能夠返回屢次值
三、函數暫停與再繼續運行的狀態是有yield保存
1 # 2 def func(count): 3 print('start') 4 while True: 5 yield count 6 count+=1 7 8 g=func(10) 9 # print(g) 10 print(next(g)) 11 12 print(next(g))
yield的表達式形式的應用
吃飯的過程,三種方法:
1 #yield的表達式形式的應用 2 #吃飯的過程 3 ##方法一: 4 def eater(name): 5 print('%s 說:我要開始吃東西啦!' %name) 6 food_list = [] #定義一個菜單空列表 7 while True: 8 # food=yield #yield 沒有返回值,後面須要給yield賦值,只要函數中有yield關鍵字,函數執行的結果就是一個生成器 9 food=yield food_list #返回值 菜單列表 10 food_list.append(food) #往列表中添加值 11 print('%s eat %s !' %(name,food)) 12 13 alex_g=eater('alex') #函數要執行下,才能獲得一個生成器 14 # print(alex_g) #是個生成器 <generator object eater at 0x0000000006B522B0> 15 16 # print(next(alex_g)) #執行結果 None 17 # print('==============>') 18 # print(next(alex_g)) #執行結果 alex eat None , food沒有接收到值 ,因此每次都要給food傳一個值,經過yield取值賦值給food 19 # print('==============>') 20 # print(next(alex_g)) 21 #第一階段 初始化 next() 生成器剛開始的時候,必須給一個None值 22 next(alex_g) #保證在初始的位置,簡單的觸發生成器的執行,保證函數停在yield位置 等同於 alex_g.send(None) 23 print('==========>') 24 25 #第二階段 給yield傳值 經過alex_g.send() 發送值 26 alex_g.send('包子') #發送值 先給當前暫停位置的yield傳值 , 執行結果爲: alex eat 包子 27 #繼續往下執行,直到再次碰到yield,而後暫停,而且把yield後的返回值當作本次調用的返回值 28 # alex_g.send('八寶粥') #發送值 29 print(alex_g.send('八寶粥')) 30 print(alex_g.send('煎餃'))
1 ##方法二: 2 ##修改第二階段 3 4 def eater(name): 5 print('%s 說:我要開始吃東西啦!' %name) 6 food_list = [] #定義一個菜單空列表 7 while True: 8 food=yield food_list #返回值 菜單列表 9 food_list.append(food) #往列表中添加值 10 print('%s eat %s !' %(name,food)) 11 12 alex_g=eater('alex') #函數要執行下,才能獲得一個生成器 13 14 next(alex_g) 15 print('==========>') 16 17 ##第二階段傳值的功能寫成一個交互函數 18 19 def producer(): 20 alex_g=eater('alex') 21 #第一階段:初始化 22 next(alex_g) 23 #第二階段:給yield傳值 24 while True: 25 food=input('>>: ').strip() 26 if not food:continue 27 print(alex_g.send(food)) 28 29 30 producer() 31 ##############################
1 ##方法三: 2 3 #不容易記得初始化 4 #用裝飾器解決初始化問題 5 ####裝飾器基本形式 6 ''' 7 def init(func): 8 def wrapper(*args, **kwargs): 9 pass 10 return wrapper 11 ''' 12 ##先寫個什麼都沒幹的裝飾器 13 ''' 14 def init(func): 15 def wrapper(*args, **kwargs): 16 g = func(*args, **kwargs) 17 return g 18 return wrapper 19 ''' 20 #完成調用初始化工做 21 def init(func): 22 def wrapper(*args, **kwargs): 23 g = func(*args, **kwargs) 24 next(g) #調用next()初始化 25 return g 26 return wrapper 27 @init #將裝飾器加在目錄函數上 28 def eater(name): 29 print('%s 說:我要開始吃東西啦!' %name) 30 food_list = [] #定義一個菜單空列表 31 while True: 32 # food=yield #yield 沒有返回值,後面須要給yield賦值,只要函數中有yield關鍵字,函數執行的結果就是一個生成器 33 food=yield food_list #返回值 菜單列表 34 food_list.append(food) #往列表中添加值 35 print('%s eat %s !' %(name,food)) 36 37 alex_g=eater('alex') 38 alex_g.send('包子') 39 print(alex_g.send('八寶粥')) 40 print(alex_g.send('煎餃'))
面向過程
面向過程:核心是過程二字,明確的區分幾個階段,
基於面向過程去設計程序就像是在設計一條工業流水線,是一種機械式的思惟方式
過程即解決問題的步驟
寫程序要先設計
優勢:程序結構清晰,能夠把負責的問題簡單化,流程化
缺點:可擴展性差,一條流水線只是用來解決一個問題
應用場景:Linux內核, Git, httpd, shell腳本
1 ##遍歷目錄下的全部文件 2 #三種方式 3 #1、普通方式: 4 import os #導入os模塊,os下面有個walk模塊,他是個生成器 5 import time 6 7 #第一階段:找到全部文件的絕對路徑 8 #使用os.walk()的方法,將walk生成的元組裏的元素拼接成絕對路徑 9 def search(filepath): 10 g=os.walk(filepath) 11 for pardir,_,files in g: 12 for file in files: 13 abspath = r'%s\%s' %(pardir,file) 14 print(abspath) 15 fp = input('請輸入目錄絕對路徑:') 16 search(r'%s' % (fp)) 17 time.sleep(10) 18 19 ##2、裝飾器方式,手動初始化裝飾器 20 import os #導入os模塊,os下面有個walk模塊,他是個生成器 21 import time 22 23 #第一階段:找到全部文件的絕對路徑 24 #使用os.walk()的方法,將walk生成的元組裏的元素拼接成絕對路徑 25 def search(): 26 while True: 27 filepath = yield 28 g=os.walk(filepath) 29 for pardir,_,files in g: 30 for file in files: 31 abspath = r'%s\%s' %(pardir,file) 32 print(abspath) 33 34 fp = input('請輸入目錄絕對路徑:') 35 g = search() #使用裝飾器,要先初始化 36 next(g) #初始化 37 38 g.send(r'%s' % (fp)) 39 time.sleep(10) 40 41 ##3、自動初始化裝飾器 42 import os #導入os模塊,os下面有個walk模塊,他是個生成器 43 import time 44 45 def init(func): #解決初始化問題 46 def wrapper(*args,**kwargs): 47 g=func(*args,**kwargs) 48 next(g) 49 return g 50 return wrapper 51 @init 52 #第一階段:找到全部文件的絕對路徑 53 #使用os.walk()的方法,將walk生成的元組裏的元素拼接成絕對路徑 54 def search(): 55 while True: 56 filepath = yield 57 g=os.walk(filepath) 58 for pardir,_,files in g: 59 for file in files: 60 abspath = r'%s\%s' %(pardir,file) 61 print(abspath) 62 # g = search('Null') 63 # next(g) 64 fp = input('請輸入目錄絕對路徑:') 65 66 g = search() #使用裝飾器,要先初始化 67 # next(g) #初始化 68 g.send(r'%s' % (fp)) 69 time.sleep(10)
1 #面向過程:核心是過程二字 2 #過程即解決問題的步驟 3 #寫程序要先設計 4 5 6 #grep -rl 'error' /dir/ 7 #-r是遞歸着找,-l 是系列出文件名 ,找出目錄下的全部文件,打開文件,找出有 error 的關鍵字,列出包含error的行的文件名 8 #思路:找出全部文件的絕對路徑、打開文件、循環逐行讀取每行文件內容、判斷error是否在文件裏(過濾)、打印改行屬於的文件名 9 import os #導入os模塊,os下面有個walk模塊,他是個生成器 10 def init(func): #寫一個裝飾器,完成調用初始化工做 11 def wrapper(*args,**kwargs): 12 g=func(*args,**kwargs) 13 next(g) 14 return g 15 return wrapper 16 17 #第一階段:找到全部文件的絕對路徑 18 #使用os.walk()的方法,將walk生成的元組裏的元素拼接成絕對路徑 19 def search(filepath): 20 g=os.walk(filepath) 21 for parddir,_,file in g: 22 for file in files: 23 abspath = r'%S\%s' %(pardir,file) 24 print(abspath) 25 search(r'F:\study\18期') 26 @init 27 def search(target): #定義一個找路徑的功能 28 while True: 29 filepath=yield 30 g=os.walk(filepath) #生成器,使用next()方法,能夠讀取該文件的路徑、目錄、文件名,並將其爲元素組成一個元組。 31 for pardir,_,files in g: 32 for file in files: 33 abspath=r'%s\%s' %(pardir,file) 34 target.send(abspath) 35 # search(r'C:\Users\Administrator\PycharmProjects\python123\day5\aaa') 36 # g=search() 37 # g.send(r'C:\Python27') 38 39 #第二階段:打開文件 40 @init 41 def opener(target): 42 while True: 43 abspath=yield 44 with open(abspath,'rb') as f: 45 target.send((abspath,f)) 46 47 48 49 50 #第三階段:循環讀出每一行內容 51 @init 52 def cat(target): 53 while True: 54 abspath,f=yield #(abspath,f) 55 for line in f: 56 res=target.send((abspath,line)) 57 if res:break 58 59 60 61 #第四階段:過濾 62 @init 63 def grep(pattern,target): 64 tag=False 65 while True: 66 abspath,line=yield tag 67 tag=False 68 if pattern in line: 69 target.send(abspath) 70 tag=True 71 72 73 #第五階段:打印該行屬於的文件名 74 @init 75 def printer(): 76 while True: 77 abspath=yield 78 print(abspath) 79 80 g = search(opener(cat(grep('os'.encode('utf-8'), printer())))) 81 # g.send(r'C:\Users\Administrator\PycharmProjects\python123\day5\aaa') 82 83 g.send(r'C:\Users\Administrator\PycharmProjects\python234') 84 #a1.txt,a2.txt,b1.txt
#遞歸
'''
遞歸調用:再調用一個函數的過程當中,直接或間接的調用了函數自己
python中遞歸的效率不高
記錄下一次遞歸,保留上一次遞歸的狀態,python對遞歸層級作了限制,默認1000層
程序中必須有個明確的結束條件
1 直接調用: 2 #直接 3 # def func(): 4 # print('from func') 5 # func() 6 # 7 # func() #直接 8 9 #間接 10 # def foo(): 11 # print('from foo') 12 # bar() 13 # 14 # def bar(): 15 # print('from bar') 16 # foo() 17 # 18 # foo() #間接調用
迭代 每一次更新都是上一次更新的結果
遞歸 直接或間接的調用了函數自己
遞歸包含兩個階段
遞推:一層層的往下
回溯:一層層的回溯
何時用遞歸:
遞歸就是個循環的過程,遞歸能夠作的,循環能夠也能夠作,只是麻煩點
循環是要明確的知道循環多少次
遞歸不須要
1 2 #取出列表中的全部元素 3 #若果使用循環,無法判斷循環多少次,這裏用遞歸來取值 4 5 list1 =[1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15,[16,[17,]],19]]]]]]] #有不少層 6 7 8 def search(l): #定義功能,給一個l參數 9 for i in l: #循環列表l中的元素 10 if type(i) is list: #判斷若是元素是個列表 11 search(i) #重複該功能,繼續查找元素 12 else: 13 print(i) #打印該元素 14 15 search(list1) #調用該功能 16 #
二分法
##二分法(把一組元素一半一半的一直分下去) #在下列列表中,搜索某個值是否存在,若存在請提示"find it!" , 除了in,如何遍歷,使用二分法遍歷 #若搜索的是不存在的,則返回「no exist!」 l = [1,2,5,7,10,31,44,47,56,99,102,130,240,332,346.480,520,527,572,666,668,888,999] #從小到大排列(假設列表有不少值), def binary_search(l,num): print(l) #[10, 31] if len(l) > 1: mid_index=len(l)//2 #1 #把列表切一半 if num > l[mid_index]: #和中間的值比較,若是比中間值大,則要去右邊找,就要切分 #in the right l=l[mid_index:] #l=[31] binary_search(l,num) elif num < l[mid_index]: #in the left l=l[:mid_index] binary_search(l,num) else: print('find it') else: if l[0] == num: print('find it') else: print('not exist!') return binary_search(l,888) ####結果 [1, 2, 5, 7, 10, 31, 44, 47, 56, 99, 102, 130, 240, 332, 346.48, 520, 527, 572, 666, 668, 888, 999] [1, 2, 5, 7, 10, 31, 44, 47, 56, 99, 102] [1, 2, 5, 7, 10] [5, 7, 10] [7, 10] [7] not exist!