迭代器
迭代器簡單理解為一個容器,循環(huán)的時候每次從容器中取出一個數(shù)據(jù),直到容器數(shù)據(jù)取完。
自定義迭代器,需要在類中實現(xiàn)兩個方法__iter__和__next__
__iter__:方法需要返回對象本身,它是for循環(huán)使用迭代器的要求
__next__:方法用于返回容器中下一個元素,當容器中的數(shù)據(jù)取完時,需要引發(fā)StopIteration異常。
class Number():
? ? def __init__(self,min,max):
? ? ? ? self.min=min
? ? ? ? self.max=max
? ? def __iter__(self):
? ? ? ? return self
? ? def __next__(self):
? ? ? ? num =self.min
? ? ? ? if self.min<=self.max:
? ? ? ? ? ? self.min +=1
? ? ? ? ? ? return num **3
? ? ? ? else:
? ? ? ? ? ?raise StopIteration
num_list=[]
for iin Number(1,6):
? ? print(i)
? ? num_list.append(i)
print(num_list)
上面這段代碼簡單寫了一下自定義迭代器,先定義了一個Number類,初始化方法里有min和max兩個參數(shù),定義兩個方法__iter__和__next__,然后將min賦值給一個變量num,判斷min是否<=max,如果小于等于返回num的3次方。然后拋出異常,最后用for循環(huán)測試1-6之間的3次方,將值添加到列表中。注意self.min +=1,不加會死循環(huán)。
生成器
假如有一個列表,里面有很多元素,但是只想訪問其中的某幾個元素,這樣的操作會特別耗內(nèi)存。
生成器的特點:
1、可以操作海量數(shù)據(jù),節(jié)約大量內(nèi)存
2、跟普通函數(shù)不同,生成器是一個返回迭代器的函數(shù),只能用于迭代操作,更簡單的理解生成器就是一個迭代器
3、在調(diào)用生成器運行的過程中,每次遇到y(tǒng)ield時,函數(shù)會暫停并保存當前運行的所有信息,返回yield的值,并在下一次執(zhí)行next()方法時從當前位置繼續(xù)運行。
yield和return的區(qū)別
1、return會跳出當前函數(shù),yield不會跳出當前函數(shù)
2、yield保存當前函數(shù)的執(zhí)行狀態(tài),在返回后,函數(shù)又回到之前保存的狀態(tài)繼續(xù)執(zhí)行
簡單說一下閉包
閉包的特點:
1、函數(shù)內(nèi)部,再定義函數(shù)
2、內(nèi)部函數(shù)引用外部變量,但并非全局變量
3、需要把內(nèi)部函數(shù)返回
def outer():
? ? a=0
? ? def inner(b):
? ? ? ? #print("")
? ? ? ? print(a+b)
? ? ? ? return inner
f=outer()
f.__closure__[0].cell_contents
上述代碼簡單實現(xiàn)了一個閉包,在outter函數(shù)內(nèi)有一個變量a和一個inner函數(shù),inner函數(shù)引用了變量a,并返回inner,最后使用f.__closure__[0].cell_contents代碼進行檢測,如果沒有報錯那說明這個outter函數(shù)是閉包,如果報錯則不是閉包。將print("")注釋取消,注釋print(a+b),測試運行會報錯,閉包必須滿足特點中的3個條件。
裝飾器
裝飾器是一種增加函數(shù)或類功能的簡單方法,它可以快速的給不同的函數(shù)或類傳入相同的功能,調(diào)用被裝飾過的函數(shù)與之前調(diào)用函數(shù)并沒有區(qū)別。
裝飾器基本格式:
def decorate(func):? #定義裝飾器函數(shù),參數(shù)為func,代表被裝飾的函數(shù)
? ? def wrapper(*args,**kwargs):? #新定義一個包裝函數(shù),用于返回
? ? ? ? func(*args,**kwargs)? #調(diào)用被裝飾的函數(shù)
? ? return wrapper? #返回包裝函數(shù)
裝飾器的簡單用法:
@decorate
def func():
? ? print("hello func")
def func1():
? ? print("hello func1")
def func2():
? ? print("hello func2")
#定義裝飾器
def decorate(func):
? ? def wrapper(*args,**kwargs):
? ? ? ? print("開始")
? ? ? ? func(*args,**kwargs)
? ? ? ? print("結(jié)束")
? ? return wrapper
func()
func1()
func2()
只需要在調(diào)用被裝飾的函數(shù)上面或者下面添加需要的代碼,然后再原函數(shù)上用@裝飾器名正常調(diào)用函數(shù)就可以了。