迭代器

帶參裝飾器
一般,裝飾器爲被裝飾的函數添加新功能,須要外界的參數函數

-- outer參數固定一個,就是func對象

-- inner參數固定同被裝飾的函數,也不能添加新參數

-- 能夠藉助函數的嵌套定義,外層給內層傳參索引

def wrap(info):

def outer(func):

# info = 0

def inner(*args, **kwargs):

print('新:拓展的新功能,可能也須要外界的參數%s' % info)
res = func(*args, **kwargs)

return res

return inner

return outerit


@wrap('外部參數')io

def fn(): passfor循環

系統的wraps帶參裝飾器:改變inner的假指向,本質外界使用的仍是inner,可是打印顯示的是wraps中的函數import

from functools import wraps
def
outer(func):

@wraps(func)

def inner(*args, **kwargs):
容器

res = func(*args, **kwargs)

return res

return inner原理


@outer object

def fn(): pass

 

迭代對象
迭代器:循環反饋的容器(集合類型)

-- 不一樣於索引取值,但也能夠循環的從容器對象中從前日後逐個返回內部的值

優勢:不依賴索引,完成取值

缺點:不能計算長度,不能指定位取值(只能從前日後逐一取值)

 

 

可迭代對象
可迭代對象:有__iter__()方法的對象是可迭代對象,可迭代對象調用__iter__()獲得迭代器對象


ls = [4, 1, 5, 2, 3]

res = ls.__iter__() # => 可迭代對象

print(res) <list_iterator object at 0x000002732B0C7470>

 


迭代對象
迭代器對象:有__next__()方法的對象是迭代器對象,迭代器對象依賴__next__()方法進行取值


with open('1.txt', 'rb') as f:

res = f.__next__() # 文件中的第一行內容
print(res)
res = f.__next__() # 文件中的第二行內容
print(res)

 

for循環迭代器
直接用while True循環在迭代器對象中經過 __next__() 取值,取空時,取空再取值,報StopIteration異常


ls = [3, 1, 2, 3, 5]

iterator = ls.__iter__()

while True:

try:

print(iterator.__next__())

except StopIteration:

# print('取空了')

break

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

for v in ls:

print(v)


for v in ls.__iter__(): #可迭代對象.__iter__() => 迭代器對象
print(v)


iterator = ls.__iter__()

for v in iterator: # 迭代器對象.__iter__() => 自身
print(v)


for循環迭代器的工做原理:

for v in obj: pass
#
1)獲取obj.__iter__()的結果,就是獲得要操做的 迭代器對象

2)迭代器對象經過__next__()方法進行取值,依次將當前循環的取值結果賦值給v

3)當取值拋異常,自動處理StopIteration異常結束取值循環

 

 


生成器
生成器:自定義的迭代器對象

-- 就是用函數語法來聲明生成器,用yield關鍵字取代return關鍵字來返回值,參數沒有多少變化


總結:有yield關鍵字的函數,函數名() 不是調用函數,而是生成獲得 生成器對象,生成器對象就是迭代器對象,能夠經過 __next__() 進行取值


執行流程:
def fn():

yield 1

yield 3

yield 5

obj = fn()
obj.__next__()
從開始往下執行,遇到第一個yield中止,拿到yield的返回值
obj.__next__()
從上一次中止的yield往下執行,在再遇到的yield時中止,拿到當前中止的yield的返回值

...
以此類推,直到沒法得到下一個yield,拋StopIteration異常


能夠直接被for循環遍歷

for v in fn():

print v

 

案例一:建立生成器,從其取值,依次獲得1! 2! 3! ...

def jiecheng():

ji = 1

count = 1

while True:

ji *= count

yield ji

count += 1

obj = jiecheng()

print(obj.__next__())

print(obj.__next__())

print(obj.__next__()) # 能夠無限取

 

案例二:

def jiecheng_num(num):

ji = 1

for i in range(1, num + 1):

ji *= i

yield ji

# ..。


obj = jiecheng_num(3)

print(obj.__next__())

print(obj.__next__())

print(obj.__next__())

print(obj.__next__()) # 有異常了

 

for v in jiecheng_num(5):

print(v) # 會自動處理異常中止

 

案例三:
def my_range(num): # => [0, 1, 2, ..., num - 1]
count = 0

while count < num:

yield count

count += 1


for v in my_range(10):

print(v, end=' ')

print(list(my_range(10)))

相關文章
相關標籤/搜索