python3自動化學習04
概要:叠代器、yield生成器、裝飾器、遞歸函數、簡單的算法(二分查找,二維數組)、正則表達式基礎
一、叠代器
叠代器是訪問集合元素的一種方式,叠代器對象從集合的第一個元素開始訪問,知道所有的元素被訪問完結束。
叠代器只能往前不能後退。叠代器的一大優點就是不要求事先準備好整個叠代的過程中所有的元素,叠代器僅僅是在叠代到某個元素才計算該元素,而在這之前或之後,元素可以不存在或者銷毀,這個特點使它特別適用於遍歷一些巨大或無限的集合。
特點:
1.訪問者不需要關心叠代器內部的結構,僅僅需要通過 __next__() 方法不斷去獲取下一個內容
2.不能隨機訪問集合中的某個值,只能從頭到尾依次訪問
3.訪問到一半時不能回退
4.便於循環大的數據集合,節省內存
生成一個叠代器
1 #!/usr/bin/env python3 2 #author:Alnk 3 4 names = iter([‘a‘,‘b‘,‘c‘,‘d‘]) 5 print(names) 6 print(names.__next__()) 7 print(names.__next__()) 8 print(names.__next__()) 9 print(names.__next__())View Code
附加:
1 #!/usr/bin/env python3 2 #author:Alnk 3 f = open("read、readline、readlinest.txt","r") 4 5 #f.read() #把文件內容全部讀取到內存中,文件越大花費時間越長,是字符串形式 6 s1 = f.read() 7 print(s1) 8 print(type(s1)) 9 10 #f.readline() #每次只讀取一行,是字符串形式 11 s1 = f.readline() 12 print(s1) 13 print(type(s1)) 14 s2 = f.readline() 15 print(s2) 16 print(type(s2)) 17 18 #f.readlines() #把所有行讀取,然後變成一個列表的形式,文件越大花費時間越長19 s1 = f.readlines() 20 print(s1) 21 print(type(s1)) 22 23 #通過叠代的形式去讀取這個文件,是字符串 24 for i in f: 25 print(i) 26 print(type(i))‘‘‘
二、生成器 yield
一個函數調用時返回一個叠代器,那這個函數就叫生成器。如果函數中包含 yield 語法,那這個函數就會變成生成器。
1 #!/usr/bin/env python3 2 #author:Alnk 3 4 def cash_out(amount): 5 while amount > 0: 6 amount -=100 7 yield 100 8 print("又來取錢") 9 10 atm = cash_out(500) 11 print(type(atm)) 12 print(atm.__next__())View Code
yield作用:可以使函數中斷,並保存中斷狀態。中斷後,代碼可以繼續往下執行,過一段時間還可以再重新調用這個函數,從上次yield的下一句開始執行。
另外,yield還可以在單線程的情況下實現並發的運算效果
1 #!/usr/bin/env python3 2 #author:Alnk 3 import time 4 5 def consumer(name): 6 print("%s 準備吃包子啦" %(name)) 7 while True: 8 baozi = yield 9 print("包子[%s]來了,被[%s]吃了!" %(baozi,name)) 10 11 def producer(): 12 c = consumer("張三") 13 c2 = consumer("李四") 14 c.__next__() 15 c2.__next__() 16 print("勞資開始做包子啦!") 17 for i in range(5): 18 time.sleep(1) 19 print("做了2個包子") 20 c.send("肉包子") 21 c2.send(i) 22 23 producer()View Code
三、裝飾器
python裝飾器就是用於拓展原來函數功能的一種函數,這個函數的特殊之處在於它的返回值也是一個函數。使用裝飾器的好處就是可以在不用更改原函數的代碼前提下為原函數增加新的功能(例如:權限校驗、用戶認證、日誌記錄、性能測試、事務處理、緩存等)
3.1 函數定義
1 def foo(num): 2 return num + 1
可以這麽理解:上面定義了一個函數,名字叫做 foo ,也可以把 foo 理解為變量名,該變量指向一個函數對象,如下圖所示。
調用函數只需要給函數名加上括號,並傳遞必要的參數
1 value = foo(3) 2 print(value)
變量名foo現在指向 <function foo at 0x0000000001CE2EA0> 函數對象,但他也可以執行另外一個對象
1 def bar(): 2 print("bar") 3 foo = bar 4 foo() 5 bar()
幫助理解的結構圖如下
3.2函數作為返回值
在python中一切皆為對象,函數也不例外,它可以像整數一樣作為其他函數的返回值,例如:
1 def foo(): 2 return 1 3 4 def bar(): 5 return foo 6 7 print(bar()) #<function foo at 0x0000000002052EA0> 8 9 print(bar()()) 10 #等價於 11 print(foo())
調用函數 bar() 的返回值是一個函數對象 <function foo at 0x0000000002052EA0> ,因為返回值是一個函數,所以可以繼續對返回值進行調用。調用函數就是在函數名後面加上括號
幫助理解的結構圖如下
3.3 函數作為參數
函數還可以像整體一樣作為函數的參數,例如:
1 def foo(num): 2 return num + 1 3 4 def bar(fun): #fun = foo 5 return fun(3) 6 7 value = bar(foo) 8 print(value)
函數 bar 接收一個參數,這個參數是一個可被調用的函數對象,把函數 foo 傳遞到 bar 中去時, foo 和 fun 兩個變量名都指向同一個函數對象
3.4 函數嵌套
1 def outer(): 2 x = 1 3 def inner(): 4 print(x) 5 inner() 6 7 outer()
inner作為嵌套的函數,可以訪問外部的函數變量,調用outer函數發生了3件事:
給 變量x 賦值為 1
定義嵌套函數 inner,此時不會執行 inner 中的代碼,應該該函數還沒被調用
調用 inner 函數,執行inner 中的代碼
3.5 閉包
1 def outer(x): 2 def inner(): 3 print(x) 4 5 return inner 6 7 closure = outer(1) 8 closure()
稍微改動上一步驟的函數,把局部變量x 作為參數傳遞進來,嵌套函數不在直接在函數裏被調用,而是作為返回值返回,這裏的 closure 就是一個閉包,本質上它還是函數,閉包是引用了自由變量x 的函數inner
3.6 簡易的裝飾器
1 def foo(): 2 print("foo") 3 4 #需求,在執行該函數時加上日誌 5 #方法1 --該方法需要修改 foo 函數源代碼,不可取 6 #def foo(): 7 # print("日誌開始") 8 # print("foo") 9 # print("日誌結束") 10 11 #簡單的裝飾器 12 def outer(func): 13 def inner(): 14 print("日誌開始") 15 func() #業務函數 16 print("日誌結束") 17 return inner 18 19 def foo(): 20 print("foo") 21 22 foo = outer(foo) 23 foo()
這裏的 outer 函數其實就是一個裝飾器,裝飾器是一個帶有函數作為參數並返回一個新的函數的閉包,本質上裝飾器也是函數。
outer 函數的返回值就是 inner 函數,在 inner 函數中,除了執行日誌操作意外,還有業務代碼,該函數重新賦值給 foo 變量,調用 foo() 就相當於調用 inner()
foo 重新賦值以前:
重新賦值以後 foo = outer(foo)
3.7 使用裝飾器語法糖
這裏的 @outer 就相當於 foo = outer(foo)
1 def outer(func): 2 def inner(): 3 print("日誌開始") 4 func() #業務函數 5 print("日誌結束") 6 return inner 7 8 @outer 9 def foo(): 10 print("foo") 11 12 foo()
3.8 被裝飾的函數帶有參數
1 #!/usr/bin/env python3 2 #author:Alnk 3 4 def outer(fun): 5 def inner(a,b): 6 print("日誌開始") 7 fun(a,b) #業務代碼 8 print("日誌結束") 9 return inner 10 11 @outer 12 def foo(a,b): 13 print("%s foo %s " %(a,b)) 14 15 foo(3,4)
3.9 被裝飾的函數帶有不定參數
1 #!/usr/bin/env python3 2 #author:Alnk 3 4 def outer(fun): 5 def inner(*args,**kw): 6 print("日誌開始") 7 fun(*args,**kw) #業務代碼 8 print("日誌結束") 9 return inner 10 11 @outer 12 def foo(a,b): 13 print("%s foo %s " %(a,b)) 14 15 @outer 16 def f1(a,b,c): 17 print("%s f1 %s %s "%(a,b,c)) 18 19 foo(3,4) 20 print("-"*30) 21 f1(3,4,5)
4.0 多個裝飾器
1 #!/usr/bin/env python3 2 #author:Alnk 3 4 def outer1(fun): 5 def inner(*args,**kw): 6 print("日誌開始") 7 fun(*args,**kw) #業務代碼 8 print("日誌結束") 9 return inner 10 11 def outer2(fun): 12 def inner(*args, **kw): 13 print("我是第2個裝飾啊") 14 fun(*args, **kw) # 業務代碼 15 print("第2個裝飾器完工") 16 return inner 17 18 def outer3(fun): 19 def inner(*args, **kw): 20 print("我是第3個裝飾啊") 21 fun(*args, **kw) # 業務代碼 22 print("第3個裝飾器完工") 23 return inner 24 25 @outer1 26 @outer2 27 @outer3 28 def foo(a,b): 29 print("%s foo %s " %(a,b)) 30 31 foo(3,4) 32 ‘‘‘ 33 執行完結果如下: 34 日誌開始 35 我是第2個裝飾啊 36 我是第3個裝飾啊 37 3 foo 4 38 第3個裝飾器完工 39 第2個裝飾器完工 40 日誌結束 41 ‘‘‘
四、遞歸函數
pass
五、簡單的算法(二分查找,二維數組)
pass
六、正則表達式基礎
pass
python3自動化學習04