python 生成器装饰器_4.python迭代器生成器装饰器
基本概念
1.容器(container)
容器是一種把多個元素組織在一起的數(shù)據(jù)結(jié)構(gòu),容器中的元素可以逐個地迭代獲取,可以用in, not in關(guān)鍵字判斷元素是否包含在容器中。通常這類數(shù)據(jù)結(jié)構(gòu)把所有的元素存儲在內(nèi)存中(也有一些特例,并不是所有的元素都放在內(nèi)存,比如迭代器和生成器對象)在Python中,常見的容器對象有:
list, deque, ….
set, frozensets, ….
dict, defaultdict, OrderedDict, Counter, ….
tuple, namedtuple, …
str
容器比較容易理解,因為你就可以把它看作是一個盒子、一棟房子、一個柜子,里面可以塞任何東西。從技術(shù)角度來說,當(dāng)它可以用來詢問某個元素是否包含在其中時,那么這個對象就可以認(rèn)為是一個容器,比如 list,set,tuples都是容器對象.
2.可迭代對象(iterable)
凡是可以返回一個迭代器的對象都可稱之為可迭代對象
3.迭代器(iterator)
那么什么迭代器呢?它是一個帶狀態(tài)的對象,他能在你調(diào)用next()方法的時候返回容器中的下一個值,任何實現(xiàn)了__iter__和__next__()方法的對象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一個值,如果容器中沒有更多元素了,則拋出StopIteration異常,至于它們到底是如何實現(xiàn)的這并不重要。
生成器(generator)
一個包含了yield關(guān)鍵字的函數(shù)就是一個生成器,該函數(shù)也叫生成器函數(shù)。當(dāng)生成器函數(shù)被調(diào)用時,在函數(shù)體中的代碼不會被執(zhí)行,而會返回一個迭代器。每次請求一個值,就會執(zhí)行生成器中代碼,直到遇到一個yield表達(dá)式或return語句。yield表達(dá)式表示要生成一個值,return語句表示要停止生成器。換句話說,生成器是由兩部分組成,生成器的函數(shù)和生成器的迭代器。生成器的函數(shù)是用def語句定義的,包含yield部分;生成器的迭代器是這個函數(shù)返回的部分。二者合起來叫做生成器。
迭代器與生成器
1.迭代器使用舉例:
city = ['beijing','shanghai','tinajin','chongqin']
it=iter(city)print(type(it))#方法一:使用next方法來使用迭代器
print(it.__next__())print(it.__next__())
方法二:使用for循環(huán)來使用迭代器for x init:print(x)
2 用生成器函數(shù)完成與counter類似功能
defgenerator(low,high):while low <=high:yieldlow
low+= 1
for i in generator(1,10):print(i,end='')
結(jié)果:12345678910
3. 生成器產(chǎn)生無限多的值
def generator(start =0):whileTrue:yieldstart
start+= 1
for number in generator(4):print(number,end='')if number > 20:break
4. 列表生成器
a = [i*2 for i in range(1,10)]print(a)
結(jié)果:
[2, 4, 6, 8, 10, 12, 14, 16, 18]
裝飾器
要求:
不能修改被裝飾的函數(shù)的源代碼
不能修改被裝飾的函數(shù)的調(diào)用方式
滿足上面的兩種情況下給程序增添功能
組成:
< 函數(shù)+實參高階函數(shù)+返回值高階函數(shù)+嵌套函數(shù)+語法糖 = 裝飾器 >
1.簡單裝飾器
1 importtime2 deftimer(func):3 defwrapper():4 start_time =time.time()5 func()6 stop_time =time.time()7 print("run time %s"%(stop_time-start_time))8 returnwrapper9 @timer #語法糖 test=timer(test)
10 deftest():11 time.sleep(3)12 print("in the test")13 test()14
15 結(jié)果:16 inthe test17 run time 3.000171661376953。
1.test表示的是函數(shù)的內(nèi)存地址
2.test()就是調(diào)用對在test這個地址的內(nèi)容,即函數(shù)
高階函數(shù):
1.把一個函數(shù)名當(dāng)作實參傳給另外一個函數(shù)(“實參高階函數(shù)”)
2.返回值中包含函數(shù)名(“返回值高階函數(shù)”)
這里面所說的函數(shù)名,實際上就是函數(shù)的地址,把函數(shù)名當(dāng)做實參,那么也就是說可以把函數(shù)傳遞到另一個函數(shù),然后在另一個函數(shù)里面做一些操作。
嵌套函數(shù):
嵌套函數(shù)指的是在函數(shù)內(nèi)部定義一個函數(shù),而不是調(diào)用
函數(shù)只能調(diào)用和它同級別以及上級的變量或函數(shù)。也就是說:里面的能調(diào)用和它縮進(jìn)一樣的和他外部的,而內(nèi)部的是無法調(diào)用的。
把test作為參數(shù)傳遞給了timer(),此時,在timer()內(nèi)部,func = test,接下來,定義了一個wrapper()函數(shù),但并未調(diào)用,只是在內(nèi)存中保存了,并且
標(biāo)簽為wrapper。在timer()函數(shù)的最后返回wrapper()的地址wrapper。然后再把wrapper賦值給了test,那么此時test已經(jīng)不是原來的test了,也就是test原來的那些函數(shù)體的標(biāo)簽換掉了,換成了wrapper
2.裝飾有參函數(shù)
importtimedeftimer(func):def deco(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)
stop_time=time.time()print(stop_time-start_time)returndeco
@timerdeftest(parameter):
time.sleep(3)print("test is running")
test("添加參數(shù)")
3.更復(fù)雜的裝飾器
對這兩個函數(shù)分別統(tǒng)計運行時間,再加一層函數(shù)來接受參數(shù),根據(jù)嵌套函數(shù)的概念,要想執(zhí)行內(nèi)函數(shù),就要先執(zhí)行外函數(shù),才能調(diào)用到內(nèi)函數(shù)
importtimedeftimer(parameter):defouter_wrapper(func):def wrapper(*args, **kwargs):if parameter == 'task1':
start=time.time()
func(*args, **kwargs)
stop=time.time()print("the task1 run time is :", stop -start)elif parameter == 'task2':
start=time.time()
func(*args, **kwargs)
stop=time.time()print("the task2 run time is :", stop -start)returnwrapperreturnouter_wrapper
@timer(parameter='task1')deftask1():
time.sleep(2)print("in the task1")
@timer(parameter='task2')deftask2():
time.sleep(2)print("in the task2")
task1()
task2()
總結(jié)
以上是生活随笔為你收集整理的python 生成器装饰器_4.python迭代器生成器装饰器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java format用法_java学习
- 下一篇: 耶鲁大学计算机科学录取,耶鲁大学计算机科