day13 迭代器和生成器

1複習

# 函數 —— 2天
    # 函數的定義和調用
    # def 函數名(形參):
        #函數體
        #return 返回值  #被調用的地方接收
    #調用 函數名(實參)
    # 站在形參的角度上 : 位置參數,*args,默認參數(陷阱),**kwargs
    # 站在實參的角度上 : 按照位置傳,按照關鍵字傳
    # 返回值:沒有返回值 返回一個值 返回多個值
    # 接收返回值:沒有返回值不接收,返回一個值用一個變量接收,返回多個值用一個變量或者對應數目的變量接收
# 閉包函數 —— 在內部函數引用外部函數的變量
# 裝飾器函數—— 裝飾器必定是閉包函數
    # 裝飾器的做用 : 在不改變原來函數的調用方式的狀況下 在這個函數的先後添加新的功能
    # 完美的符合了一個開發原則 :開放封閉原則
        # 對擴展是開發的
        # 對修改是封閉的
    # 基礎的裝飾器
        # from functools import wraps
        # def wrapper(func):
        #     @wraps(func)
        #     def inner(*args,**kwargs):
        #          '''在函數被調用以前添加的代碼'''
        #         ret = func(*args,**kwargs)   # func是被裝飾的函數 在這裏被調用
        #         '''在函數被調用以後添加的代碼'''
        #         return ret
        #     return inner
        # 使用 —— @wrapper
        # @wrapper
        # def func():   #inner
        #     pass
        #
        # func.__name__
    # 帶參數的裝飾器
        # @wrapper -- > @warapper(argument)
        # 三層嵌套函數
        # def outer(形參):
        #     def wrapper(func):
        #         def inner(*args,**kwargs):
        #             '''在函數被調用以前添加的代碼'''
        #             ret = func(*args,**kwargs)   # func是被裝飾的函數 在這裏被調用
        #             '''在函數被調用以後添加的代碼'''
        #             return ret
        #         return inner
        #     return wrapper
        # @outer(True)
        # def func():
        #     pass
    # 多個裝飾器裝飾一個函數
        # 俄羅斯套娃

    #def wrapper1(func):
        #     @wraps(func)
        #     def inner(*args,**kwargs):
        #         print('before 1')
        #         print('******')
        #         ret = func(*args,**kwargs)   # func是被裝飾的函數 在這裏被調用
        #         '''在函數被調用以後添加的代碼'''
        #         return ret
    # def wrapper2(func):
    #     @wraps(func)
    #     def inner(*args,**kwargs):
    #         print('before 2')
    #         ret = func(*args,**kwargs)   # func是被裝飾的函數 在這裏被調用
    #         '''在函數被調用以後添加的代碼'''
    #         return ret
    #   @wrapper1
    #   @wrapper2
    #   def func():
    #       print('111')
# 迭代器和生成器 —— 兩天
# 內置函數 —— 兩天

2迭代器

1雙下方法

#雙下方法
print([1].__add__([2]))
print([1]+[2])
<<<
[1, 2]
[1, 2]
#list dic str set tuple range enumerate
print(dir([])) #告訴我列表的全部方法
ret=set(dir([]))&set(dir({}))&set(dir(""))&set(dir(range(12)))
print(ret)
print(set(dir([]))-set(dir({})))
<<<
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
{'__gt__', '__reduce_ex__', '__doc__', '__getitem__', '__len__', '__sizeof__', '__new__', '__eq__', '__delattr__', '__str__', '__reduce__', '__format__', '__repr__', '__ne__', '__le__', '__lt__', '__iter__', '__getattribute__', '__init__', '__contains__', '__subclasshook__', '__setattr__', '__dir__', '__class__', '__ge__', '__init_subclass__', '__hash__'}
{'__iadd__', '__imul__', '__mul__', 'count', 'index', 'sort', 'reverse', 'append', '__rmul__', 'extend', 'remove', 'insert', '__reversed__', '__add__'}
'''
可迭代協議: 
            
            只要能被for循環的數據類型 就必定有__iter__方法     []
            iterable 只要含有__iter__方法的都是可迭代的
迭代器協議: 
            一個列表執行了__iter__()以後的返回值就是一個迭代器 [].__iter__
            iteraor   內部含有__iter__和__next__方法的就是迭代器
            經過__next__()就能夠從迭代器中一個一個取值 :print(iterator.__next__())
for:
for循環其實就是在使用迭代器
只有是可迭代對象的時候才能用for
當咱們用一個新的變量 不肯定能不能for循環的時候 就判斷是否可迭代
判斷方法 from _collections_abc import  
        Iterable print(isinstance([],Iterable))
        print('__iter__'in dir([])) '''

2協議

#協議
print([].__iter__())  #打印迭代器直接給你內存地址
print(set(dir([].__iter__()))-set(dir([]))) #列表迭代器至關於列表的獨特方法
print([1,'a','bbb'].__iter__().__length_hint__()) #__length_hint__求元素個數
l=[1,2,3]
iterator=l.__iter__()
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
<<<
<list_iterator object at 0x0000026048DF4438>
{'__setstate__', '__next__', '__length_hint__'}
3
1
2
3

3判斷方法

#判斷方法
print('__iter__'in dir([]))
print('__iter__'in dir([].__iter__()))
from _collections_abc import  Iterable  #棄用警告:不推薦使用或導入來自collections
from collections.abc import  Iterator   #而不是「collections.abc」中的ABC
print(isinstance([],Iterator))          # 而且在python3.8中它將中止工做
print(isinstance([],Iterable)) #判斷[]是否是可迭代的
<<<
True
True
False
True

4for

#for
#只要有iter方法就能被循環  for循環其實就是在使用迭代器
l=[1,2,3]
for i in l.__iter__():
    print(i)
print([].__iter__()) #打印迭代器直接給你內存地址
print(range(10).__iter__())
print(range(10))

l=[1,2,3]
for i in l:
    print(i)
    if i ==2:
        break
<<<
1
2
3
<list_iterator object at 0x0000024B1E314208>
<range_iterator object at 0x0000024B1DFAD830>
range(0, 10)
1
2

5迭代器的好處

# 迭代器的好處
'''
從容器類型中一個個取值 會把全部值都取到
節省內存空間
    迭代器並不會在內存中佔一大塊內存
    而是隨着循環 每次生成一個next給我一個'''

l=[1,2,3,4]
iterator=l.__iter__()
while 1:
    print(iterator.__next__())
<<<
Traceback (most recent call last):
  File "C:/python全棧/me第一部分/day13 迭代器和生成器.py", line 76, in <module>
    print(iterator.__next__())
StopIteration
1
2
3
4
print(range(10000))
print(list(range(3)))
def f():
    for i in range(200):
        i="wahaha%s"%i
    return i
print(f())

<<<
range(0, 10000)
[0, 1, 2]
wahaha199

3.生成器

#3 生成器
#生成器函數 本質上就是咱們本身寫的函數
#只要含有yield關鍵字的函數都是生成器函數
#yield不能和return共用且須要寫在函數內
def generetor():
    print(1)
    yield 'a'
ret=generetor()
print(ret)
print(ret.__next__())
<<<
<generator object generetor at 0x00000246FE4C8A98>
1
a

1.生成器函數 執行以後會獲得一個生成器做爲一個返回值

#生成器函數 執行以後會獲得一個生成器做爲一個返回值
def generetor1():
    print(1)
    yield 'a'
    print(2)
    yield 'b'
    yield 'c'
g=generetor1()
print(g)
ret=g.__next__()
print(ret)
# for i in g:
#     print(i)  1 a 2 b c
ret=g.__next__()
print(ret)
ret = g.__next__()
print(ret)

<<<
1
a
2
b
c

2.next方法獲取生成器的值

# 娃哈哈
import time
def wahaha():
    for i in range(200000):
        yield '娃哈哈%s'% i
g=wahaha()
g1=wahaha()
print(g.__next__())
print(g.__next__())
print(g1.__next__())

g=wahaha()
count=0
a=time.time()
for i in g:
    count+=1
    print(i)
    if count>3:
        break
b=time.time()
print(b-a)
print("***",g.__next__())
for i in g:
    count+=1
    print(i)
    if count>6:
        break
print("&&",g.__next__())
<<<
娃哈哈0
娃哈哈1
娃哈哈0
娃哈哈0
娃哈哈1
娃哈哈2
娃哈哈3
0.0
*** 娃哈哈4
娃哈哈5
娃哈哈6
娃哈哈7
&& 娃哈哈8

4 利用生成器監聽文件輸入

#4 利用生成器監聽文件輸入
def tail(filename):
    f=open(filename,encoding='utf-8')
    while True:
        line=f.readline()
        if line.strip():
            yield line.strip()  #使用生成器在後面的操做中更靈活想加*就加
g=tail('file')
# print(g.__next__())
for i in g:
    if 'python' in i:
        print("***",i)
<<<
*** python
相關文章
相關標籤/搜索