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
 

猜你喜欢

转载自www.cnblogs.com/hi-python/p/10125328.html