1. 程式人生 > >python-學習 協程函數 模塊與包

python-學習 協程函數 模塊與包

擴展性 nco 顯式 printer 中新 二分法 執行 而已 strip

一、協程函數

 yield的用法:

1:把函數的執行結果封裝好__iter__和__next__,即得到一個叠代器
2:與return功能類似,都可以返回值,但不同的是,return只能返回一次值,而yield可以返回多次值
3:函數暫停與再繼續運行的狀態是有yield保存
技術分享
 1 # 例子1
 2 # def chi(name):
 3 #     print(‘%s 開始上菜啦~‘%name)
 4 #     cd=[]     #菜單
 5 #     while True:
 6 #         food=yield cd
 7 #         cd.append(food)
8 # print(‘%s上了一份%s‘%(name,food)) 9 # print(cd) 10 # esa=chi(‘alex‘) 11 # esa.send(‘芹菜‘) 12 # 例子2 13 # def chi(name): 14 # print(‘%s 開始上菜啦~‘%name) 15 # cd=[] #菜單 16 # while True: 17 # food=yield cd 18 # cd.append(food) 19 # print(‘%s上了一份%s‘%(name,food))
20 # def shui(): 21 # name = input(‘服務員名字>>: ‘).strip() 22 # while True: 23 # food=input(‘菜名>>: ‘).strip() 24 # sc=chi(name) 25 # next(sc)#初始化:就是讓函數執行停到yield 26 # if not food or not name :continue 27 # sc.send(food)#給yield傳值 28 # shui()
例子

  通過裝飾器初始化:

技術分享
 1 def chushi(func):
 2     def hua(*args,**kwargs):
 3         g=func(*args,**kwargs)
 4         next(g)
 5         return g
 6     return hua
 7 @chushi
 8 def chi(name):
 9     print(%s 開始上菜啦~%name)
10     cd=[]     #菜單
11     while True:
12         food=yield cd
13         cd.append(food)
14         print(%s上了一份%s%(name,food))
15         print(cd)
16 esa=chi(alex)
17 esa.send(芹菜)
18 
19 
20 
21 #例子2
22 # def chushi(func):
23 #     def hua(*args,**kwargs):
24 #         g=func(*args,**kwargs)
25 #         next(g)
26 #         return g
27 #     return hua
28 # @chushi
29 # def chi(name):
30 #     print(‘%s 開始上菜啦~‘%name)
31 #     cd=[]     #菜單
32 #     while True:
33 #         food=yield cd
34 #         cd.append(food)
35 #         print(‘%s上了一份%s‘%(name,food))
36 # def shui():
37 #     name = input(‘服務員名字>>: ‘).strip()
38 #     while True:
39 #         food=input(‘菜名>>: ‘).strip()
40 #         sc=chi(name)
41 #         # next(sc)#初始化:就是讓函數執行停到yield
42 #         if not food or not name :continue
43 #         sc.send(food)#給yield傳值
44 # shui()
例子

二、面向過程編程

面向過程:核心是過程二字,過程即解決問題的步驟,基於面向過程去設計程序就像是在設計
一條工業流水線,是一種機械式的思維方式
優點:程序結構清晰,可以把復雜的問題簡單化,流程化
缺點:可擴展性差,一條流線只是用來解決一個問題
應用場景:linux內核,git,httpd,shell腳本

技術分享
 1 import os
 2 def init(func):
 3     def wrapper(*args,**kwargs):
 4         g=func(*args,**kwargs)
 5         next(g)
 6         return g
 7     return wrapper
 8 
 9 #第一階段:找到所有文件的絕對路徑
10 @init
11 def search(target):
12     while True:
13         filepath=yield
14         g=os.walk(filepath)
15         for pardir,_,files in g:
16             for file in files:
17                 abspath=r%s\%s %(pardir,file)
18                 target.send(abspath)
19 # search(r‘C:\Users\Administrator\PycharmProjects\python18期周末班\day5\aaa‘)
20 # g=search()
21 # g.send(r‘C:\Python27‘)
22 
23 #第二階段:打開文件
24 @init
25 def opener(target):
26     while True:
27         abspath=yield
28         with open(abspath,rb) as f:
29             target.send((abspath,f))
30 
31 
32 
33 
34 #第三階段:循環讀出每一行內容
35 @init
36 def cat(target):
37     while True:
38         abspath,f=yield #(abspath,f)
39         for line in f:
40             res=target.send((abspath,line))
41             if res:break
42 
43 
44 
45 #第四階段:過濾
46 @init
47 def grep(pattern,target):
48     tag=False
49     while True:
50         abspath,line=yield tag
51         tag=False
52         if pattern in line:
53             target.send(abspath)
54             tag=True
55 
56 
57 #第五階段:打印該行屬於的文件名
58 @init
59 def printer():
60     while True:
61         abspath=yield
62         print(abspath)
63 
64 g = search(opener(cat(grep(os.encode(utf-8), printer()))))
65 # g.send(r‘C:\Users\Administrator\PycharmProjects\python18期周末班\day5\aaa‘)
66 
67 g.send(rC:\Users\Administrator\PycharmProjects\python18期周末班)
68 #a1.txt,a2.txt,b1.txt
grep -rl ‘error‘ /dir/

三、遞歸與二分法

  遞歸調用:在調用一個函數的過程中,直接或間接地調用了函數本身

技術分享
 1 #直接
 2 # def func():
 3 #     print(‘from func‘)
 4 #     func()
 5 #
 6 # func()
 7 
 8 #間接
 9 # def foo():
10 #     print(‘from foo‘)
11 #     bar()
12 #
13 # def bar():
14 #     print(‘from bar‘)
15 #     foo()
16 #
17 # foo()
例子 

  遞歸的執行分為兩個階段:
    1 遞推
    2 回溯

技術分享
 1  l =[1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15,[16,[17,]],19]]]]]]]
 2 
 3  def search(l):
 4      for item in l:
 5          if type(item) is list:
 6              search(item)
 7          else:
 8              print(item)
 9 
10  search(l)
例子

  二分法

技術分享
 1 #例子1
 2  l = [1,2,5,7,10,31,44,47,56,99,102,130,240]
 3 
 4 
 5  def binary_search(l,num):
 6      print(l) [10, 31]
 7      if len(l) > 1:
 8          mid_index=len(l)//2 1
 9          if num > l[mid_index]:
10              in the right
11              l=l[mid_index:] l=[31]
12              binary_search(l,num)
13          elif num < l[mid_index]:
14              in the left
15              l=l[:mid_index]
16              binary_search(l,num)
17          else:
18              print(find it)
19      else:
20          if l[0] == num:
21              print(find it)
22          else:
23              print(not exist)
24          return
25 
26  binary_search(l,32)
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 #例子2
45 l = [1,2,5,7,10,31,44,47,56,99,102,130,240]
46 
47 
48 def binary_search(l,num):
49     print(l)
50     if len(l) == 1:
51         if l[0] == num:
52             print(find it)
53         else:
54             print(not exists)
55         return
56     mid_index=len(l)//2
57     mid_value=l[mid_index]
58     if num == mid_value:
59         print(find it)
60         return
61     if num > mid_value:
62         l=l[mid_index:]
63     if num < mid_value:
64         l=l[:mid_index]
65     binary_search(l,num)
66 
67 binary_search(l,32)
例子

四、模塊與包

 1.模塊只在第一次導入時才會執行,之後的導入都是直接引用內存已經存在的結果

   模塊搜索路徑:  
   內存中--》內置模塊————》sys.path

  註意:自定義的模塊名一定不要與python自帶的模塊名重名

 2.什麽是模塊

   常見的場景:一個模塊就是一個包含了python定義和聲明的文件,文件名就是模塊名字加上.py的後綴。

但其實import加載的模塊分為四個通用類別: 

  1 使用python編寫的代碼(.py文件)

  2 已被編譯為共享庫或DLL的C或C++擴展

  3 包好一組模塊的包

  4 使用C編寫並鏈接到python解釋器的內置模塊

 3.import的導入

技術分享
 1 #spam.py
 2 print(from the spam.py)
 3 
 4 money=1000
 5 
 6 def read1():
 7     print(spam->read1->money,money)
 8 
 9 def read2():
10     print(spam->read2 calling read)
11     read1()
12 
13 def change():
14     global money
15     money=0
span.py

導入span模塊

技術分享
1 #test.py
2 import spam #只在第一次導入時才執行spam.py內代碼,此處的顯式效果是只打印一次‘from the spam.py‘,當然其他的頂級代碼也都被執行了,只不過沒有顯示效果.
3 import spam
4 import spam
5 import spam
6  ‘‘‘
7  執行結果:
8  from the spam.py
9  ‘‘‘
例子

可以使用__all__來控制*(用來發布新版本)

在spam.py中新增一行

__all__=[‘money‘,‘read1‘] #這樣在另外一個文件中用from spam import *就這能導入列表中規定的兩個名字

  4.rom.......import的導入

    優點:使用源文件內的名字時無需加前綴,使用方便
    缺點:容易與當前文件的名稱空間內的名字混淆

 

  5.絕對導入和相對導入

技術分享
1 在glance/api/version.py
2 
3 #絕對導入
4 from glance.cmd import manage
5 manage.main()
6 
7 #相對導入
8 from ..cmd import manage
9 manage.main()
例子

1. 無論是import形式還是from...import形式,凡是在導入語句中(而不是在使用時)遇到帶點的,都要第一時間提高警覺:這是關於包才有的導入語法

2. 包是目錄級的(文件夾級),文件夾是用來組成py文件(包的本質就是一個包含__init__.py文件的目錄)

3. import導入文件時,產生名稱空間中的名字來源於文件,import 包,產生的名稱空間的名字同樣來源於文件,即包下的__init__.py,導入包本質就是在導入該文件

強調:

  1. 在python3中,即使包下沒有__init__.py文件,import 包仍然不會報錯,而在python2中,包下一定要有該文件,否則import 包報錯

  2. 創建包的目的不是為了運行,而是被導入使用,記住,包只是模塊的一種形式而已,包即模塊

python-學習 協程函數 模塊與包