日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

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

復習

函數的嵌套定義:在函數內部定義另一個函數

閉包:被嵌套的函數
-- 1.外層通過形參給內層函數傳參
-- 2.返回內部函數對象---->??延遲執行,

?

開放封閉原則: 功能可以拓展,但源代碼與調用方式都不可以改變

裝飾器:裝飾器名就是外層函數 @outer

@outer? # fn = outer(fn)

def fn(): pass

今日內容

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

?

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

-- outer參數固定一個,就是func
-- inner參數固定同被裝飾的函數,也不能添加新參數
?-- 可以借助函數的嵌套定義,外層給內層傳參,

?

2. 系統 functools 的wraps帶參裝飾器:inner本來是裝飾原函數func的,但func還有部分功能inner沒有,那就給inner加一個裝飾器,把這此功能裝到inner函數上,將原函數的部分功能裝飾給inner,從面達到對原函數func更好的裝飾。(通過改變inner的假指向,本質外界使用的還是inner,但是打印顯示的是wraps中原函數的id)

3.? 迭代器 :

? ? 優點:

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

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

? ? 缺點:

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

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

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

?

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 ,結束

?

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

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

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

? ? ? ? ? (為了與可迭代對象建立一個統一的標準:迭代器協議。如for 循環、max、min、reduce、sorted等,不管是可迭代對象還是迭代器對象,統一都先調用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) #若想再取值,只需重新生成一個迭代器

總結:
可迭代對象,但凡有_iter_方法的對象都是可迭代的對象。例如:list,dict,tuple,set,f
迭代器對象:既內置有_iter_方法又內置有_next_方法的對象稱之為迭代器對象,例如f
可迭代對象._iter_() --> 迭代器對象
迭代器對象._iter_() --> 迭代器本身
迭代器對象._next_() --> 迭代器的下一個值

4.for循環--本質應該稱為迭代器循環

? 為何要有for 迭代器循環?

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

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

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

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

for k in dic:

? ? ? print(k)

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

for循環就是對while取迭代器對象的封裝??

for循環迭代器的工作原理:
?for v in obj: pass
1)獲取obj.__iter__()的結果,就是得到要操作的 迭代器對象
2)迭代器對象通過__next__()方法進行取值,依次將當前循環的取值結果賦值給v
3)當取值拋異常,自動處理StopIteration異常,結束循環取值

5.?枚舉對象給可迭代器對象及迭代器對象添加迭代索引

? ? s = 'abc'
? ? for v in enumerate(s):
? ? ? ? ? ? ? print(v)? ? ?# (0 'a') | (1 'b') | (2 'c')

?

6.?生成器 :本質上就是一種自定義的迭代器

? ? ? ? ? ? ? ? ? ? 但凡函數內包含yield關鍵字,調用函數不會執行函數體代碼,會得到一個返回值,該返回值就是生成器對象

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 會觸發函數的執行,直到碰到一個yield停下來,并將yield后的值當作本次next的結果返回 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')

#強調:針對表達式形式的yield的使用,第一步必須讓函數暫停到一個yield的位置,才能進行傳值操作
#next(g) #張開狗嘴,讓生成器先暫停到yield的位置,準備接受外部傳進來的值
next(g) # g.send(None) g.send('屎包子') #兩個動作,1.先傳給暫停位置yield賦值,2,next(生成器)直到再次碰到一個yield停下來,然后將該yield后的值當做本次next的結果
g.send('菜包子')
g.send('肉包子')

總結 yield:只能在函數內使用
#1.yield提供了一種自定義迭代器的解決方案
#2.yield 可以保存函數的暫停的狀態
#3.yield對比return:
--、相同點:都可以返回值,值的類型與個數都沒有限制
--、不同點:yield可以返回多次值,而return只能返回一次值,函數就結束了

?生成器表達式:

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

應用場景:如統計文件的長度(不能讀出所有的內容),迭代一個計算一個

with open(...)? as f:

res = sun( len(line)? for line in f? )? #迭代一個加一個,

?

轉載于:https://www.cnblogs.com/qingqinxu/p/10790548.html

總結

以上是生活随笔為你收集整理的python学习Day14 带参装饰器、可迭代对象、迭代器对象、for 迭代器工作原理、枚举对象、生成器及生成表达式...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。