python学习Day14 带参装饰器、可迭代对象、迭代器对象、for 迭代器工作原理、枚举对象、生成器及生成表达式...
函數(shù)的嵌套定義:在函數(shù)內(nèi)部定義另一個函數(shù)
閉包:被嵌套的函數(shù)
-- 1.外層通過形參給內(nèi)層函數(shù)傳參
-- 2.返回內(nèi)部函數(shù)對象---->??延遲執(zhí)行,
?
開放封閉原則: 功能可以拓展,但源代碼與調(diào)用方式都不可以改變
裝飾器:裝飾器名就是外層函數(shù) @outer
@outer? # fn = outer(fn)
def fn(): pass
?
-- outer參數(shù)固定一個,就是func
-- inner參數(shù)固定同被裝飾的函數(shù),也不能添加新參數(shù)
?-- 可以借助函數(shù)的嵌套定義,外層給內(nèi)層傳參,
?
2. 系統(tǒng) functools 的wraps帶參裝飾器:inner本來是裝飾原函數(shù)func的,但func還有部分功能inner沒有,那就給inner加一個裝飾器,把這此功能裝到inner函數(shù)上,將原函數(shù)的部分功能裝飾給inner,從面達到對原函數(shù)func更好的裝飾。(通過改變inner的假指向,本質(zhì)外界使用的還是inner,但是打印顯示的是wraps中原函數(shù)的id)
?
dic = {'x':1, 'y':2, 'z':3}iter_dic = dic.__iter__()
print(iter_dic.__next__()) # x。/。/。/
print(iter_dic.__next__()) # y
print(iter_dic.__next__()) # z
print(iter_dic.__next__()) # 取空報錯:StopIteration ,結(jié)束
?
? ? ??
dic = {'x':1, 'y':2, 'z':3}iter_dic = iter(dic) # dic.__iter__()
while True:
try:
print(next(iter_dic))
except StopIteration: #捕捉異常
break # x y z
iter_dic.__next__() #StopIteration #同一個迭代器對象取空后不能再取,
iter_dic = iter(dic) #若想再取值,只需重新生成一個迭代器
總結(jié):
可迭代對象,但凡有_iter_方法的對象都是可迭代的對象。例如:list,dict,tuple,set,f
迭代器對象:既內(nèi)置有_iter_方法又內(nèi)置有_next_方法的對象稱之為迭代器對象,例如f
可迭代對象._iter_() --> 迭代器對象
迭代器對象._iter_() --> 迭代器本身
迭代器對象._next_() --> 迭代器的下一個值
for循環(huán)就是對while取迭代器對象的封裝??
for循環(huán)迭代器的工作原理:
?for v in obj: pass
1)獲取obj.__iter__()的結(jié)果,就是得到要操作的 迭代器對象
2)迭代器對象通過__next__()方法進行取值,依次將當前循環(huán)的取值結(jié)果賦值給v
3)當取值拋異常,自動處理StopIteration異常,結(jié)束循環(huán)取值
5.?
? ? s = 'abc'
? ? for v in enumerate(s):
? ? ? ? ? ? ? print(v)? ? ?# (0 'a') | (1 'b') | (2 'c')
?
6.?
def func():
print('first')
yield 1
print('second')
yield 2
print('third')
yield 3
print('fourth')
g =func()
print(g) # <generator object func at 0x000001B97FF91D58> res1 = next(g) # first 會觸發(fā)函數(shù)的執(zhí)行,直到碰到一個yield停下來,并將yield后的值當作本次next的結(jié)果返回 print(res1)
#print(res1) # 1 res2 = next(g) #second
# print(res2) # 2 res3 = next(g) # third
#print(res3) # 3 res4 = next(g) #fourth StopIteration
# print(res4)
?
?
def my_range(start, stop, step):while start < stop:
yield start
start +=step
obj = my_range(1,10, 2)
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
例1:自定一個生成器,拿來使用
def my_range(start, stop, step=1):
while start < stop:
yield start
start+=step
for i in my_range(1, 10, 2):
print(i) # 1,3, 5, 7,9
? 了解(*):yield 的表達式形式的應用: x = yield
?
def dog(name):print('狗哥%s準備吃'% name)
while True:
food = yield # food = yield = '屎包子'
print('%s 吃了%s' %(name, food))
g = dog('alex')
#強調(diào):針對表達式形式的yield的使用,第一步必須讓函數(shù)暫停到一個yield的位置,才能進行傳值操作
#next(g) #張開狗嘴,讓生成器先暫停到y(tǒng)ield的位置,準備接受外部傳進來的值
next(g) # g.send(None) g.send('屎包子') #兩個動作,1.先傳給暫停位置yield賦值,2,next(生成器)直到再次碰到一個yield停下來,然后將該yield后的值當做本次next的結(jié)果
g.send('菜包子')
g.send('肉包子')
總結(jié) yield:只能在函數(shù)內(nèi)使用
#1.yield提供了一種自定義迭代器的解決方案
#2.yield 可以保存函數(shù)的暫停的狀態(tài)
#3.yield對比return:
--、相同點:都可以返回值,值的類型與個數(shù)都沒有限制
--、不同點:yield可以返回多次值,而return只能返回一次值,函數(shù)就結(jié)束了
?生成器表達式:
g? = (i **2 for i in range(1, 10) if i > 3)
print(g)? ? # <generator object <genexpr> at 0x000002313F351D58> 不next就不會有值
print(next(g))? #16
print(next(g))? #25
應用場景:如統(tǒng)計文件的長度(不能讀出所有的內(nèi)容),迭代一個計算一個
with open(...)? as f:
res = sun( len(line)? for line in f? )? #迭代一個加一個,
?
轉(zhuǎn)載于:https://www.cnblogs.com/qingqinxu/p/10790548.html
總結(jié)
以上是生活随笔為你收集整理的python学习Day14 带参装饰器、可迭代对象、迭代器对象、for 迭代器工作原理、枚举对象、生成器及生成表达式...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大型互联网架构概述,看完文章又涨知识了
- 下一篇: django设置cookie和sessi