• 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
    
    
  • 相关阅读:
    Uliweb模板分析
    从高宏伟处借来的HOOK API代码
    ActiveX获取脚本对象
    uliweb数据库分析
    Java初入门(from c++ 2 java)(一)
    VS2010调试sharepoint2010经常Web服务器进程由IIS终止 的解决办法
    SharePoint 2010 部署 WSP 包
    sharepoint 2010 "若要在 Visual Studio 中与 SharePoint 项目进行交互,您的系统用户帐户必须拥有管理员特权。"的解决方法
    SQL 2008 安装问题 共享功能目录(x86) 服务提供的凭据无效 解决版本
    SharePoint 2010 网站集 备份 还原
  • 原文地址:https://www.cnblogs.com/hi-python/p/10125328.html
Copyright © 2020-2023  润新知