日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python学习Day14 带参装饰器、可迭代对象、迭代器对象、for 迭代器工作原理、枚举对象、生成器及生成表达式...

發(fā)布時間:2025/6/17 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python学习Day14 带参装饰器、可迭代对象、迭代器对象、for 迭代器工作原理、枚举对象、生成器及生成表达式... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

復習

函數(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

今日內(nèi)容

1.帶參裝飾器? |? 2.wrapper? |? 3.可迭代對象 |? ?4.迭代器對象? |? 5.for 迭代器工作原理 |? 6.枚舉對象 | 7.生成器

?

1. 帶參裝飾器 :?通常,裝飾器為被裝飾的函數(shù)添加新功能,需要外界的參數(shù):可以在 outer外再套一層函數(shù),通過形參給內(nèi)部傳參

-- 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)

3.? 迭代器 :

? ? 優(yōu)點:

? ? -- 、提供了一種通用的不依賴于索引的迭代取值方法

? ? -- 、同一時刻在內(nèi)存中只存在一個值,更節(jié)省空間 (只有一個iterator內(nèi)存地址)

? ? 缺點:

? ? ?-- 、取值不如按照索引、'key'的方式靈活,(不能取指定的某一個值,而且只能往后取)

? ? ?-- 、無法預測迭代器的長度

1)可迭代對象:有__iter__()方法的對象是可迭代對象,調(diào)用__iter__()返回的值, 就是一個迭代器對象iterator :除了數(shù)字類型,都是可迭代對象。

?

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é)束

?

2)? 迭代器對象: 迭代取值的工具。一個重復的過程,一個基于上次結(jié)果往后取值的過程。

? ? ?--、既有__next__()方法,執(zhí)行__next__()方法可以不依賴索引取值,((運行一個__next__()就取到一個值),直到被取空,拋出? “?StopIteration異常?")

? ? ?-- 、又有_iter_方法, 執(zhí)行 迭代器_iter_方法得到的仍然是迭代器本身.

? ? ? ? ? (為了與可迭代對象建立一個統(tǒng)一的標準:迭代器協(xié)議。如for 循環(huán)、max、min、reduce、sorted等,不管是可迭代對象還是迭代器對象,統(tǒng)一都先調(diào)用iter方法)

PS: 迭代器對象一定是可迭代的對象,而可迭代的對象卻不一定是迭代器對象。如文件對象就是一個可迭代器對象,也是一個迭代器對象

? ? ??

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_() --> 迭代器的下一個值

4.for循環(huán)--本質(zhì)應該稱為迭代器循環(huán)

? 為何要有for 迭代器循環(huán)?

? #1. 先調(diào)用in后面那個對象的iter方法,將其變成一個迭代器對象

? #2. 調(diào)用next(迭代器),將得到的返回值賦值給變量名K

? #3. 循環(huán)往復直到next(迭代器)拋出異常,for會自動捕捉異常然后結(jié)束循環(huán)

dic = {'x':1, 'y':2, 'z':3}

for k in dic:

? ? ? print(k)

? 直接用while True循環(huán):在迭代器對象中通過 __next__() 取值,終究會有取空的時候,取空再取值,報StopIteration異常

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.?生成器 :本質(zhì)上就是一種自定義的迭代器

? ? ? ? ? ? ? ? ? ? 但凡函數(shù)內(nèi)包含yield關鍵字,調(diào)用函數(shù)不會執(zhí)行函數(shù)體代碼,會得到一個返回值,該返回值就是生成器對象

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)

?

例1:自定一個生成器,

?

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。