zoukankan      html  css  js  c++  java
  • 11.迭代器与生成器、模块与包

    1.迭代器和生成器

    迭代器

    迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和__next__()方法。
    其中__iter__()方法返回迭代器对象本身;__next__()方法返回容器的下一个元素,在结尾时引发StopIteration异常。

    #迭代器 iterator
    li = [1,2]
    del li
    
    li = []
    ##for i in range(11):
    ##    if i%2==0:
    ##        li.append(i)
    
    for i in range(0,11,2):
        li.append(i)
    class TupleIter:
        def __init__(self,li):
            self.li = li
            self._index = 0
        def __iter__(self):
            return self
        def __next__(self):
            if self._index < len(self.li):
                index = self.li[self._index]
                self._index += 1
                return index
            else:
                raise StopIteration
    
    tu = TupleIter((1,2,3,4,5))

    生成器

        在Python中,使用生成器可以很方便的支持迭代器协议。
        生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。
        
        也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态。
        生成器函数返回生成器的迭代器。 “生成器的迭代器”这个术语通常被称作”生成器”。
        要注意的是生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法,
        其中一个就是__next__()。如同迭代器一样,我们可以使用__next__()函数来获取下一个值。
        
        在一个 generator function 中,如果没有 return,则默认执行至函数完毕,如果在执行过程中 return,
        则直接抛出 StopIteration 终止迭代。 
    def fun(n):
        i = 0
        while i < n:
            print('***',i)
            yield i
            i += 1
            print('+++',i)
    
    a = fun(5)
    
    """
    yield可以暂停函数的执行,所以可以占用很少的空间,不会一直占用很大的内存
    """
    import time
    def run_time(func):
        def new_fun(*args):
            t0 = time.time()
            print('star time: %s'%(time.strftime('%x',time.localtime())) )
            back = func(*args)
            print('end time: %s'%(time.strftime('%x',time.localtime())) )
            print('run time: %s'%(time.time() - t0))
            return back
        return new_fun
    
    @run_time
    def fab(maxnu):
        n,a,b = 0,0,1
        while n < maxnu:
            print(b)
            a,b = b,a+b
            n = n+1
    ##@run_time
    def fab2(maxnu):
        n,a,b = 0,0,1
        while n < maxnu:
            yield b
            a,b = b,a+b
            n = n+1
    
    b = fab2(100)
    next(b) # next(b) 就是next函数调用 b 的 __next__() return b.__next__()

    列表推导式

    #列表推导式
    l2 = [i for i in range(11)]  
    l3 = [i for i in range(11) if i%2 == 0 ]
    l4 = [i*2 for i in range(11) if i%2 == 0]
    
    {i for i in range(10)}
    {i:str(i) for i in range(10)}
    
    [i if i%2==0 else str(i) for i in range(10)]

    2.模块和包

    1.内置模块
        本身就带有的库,就叫做Python的内置的库。(模块==库)
        一些常见的内置模块
        os 和操作系统相关     os.path
        sys 和系统相关      sys.path  
            sys.path.append(r'')    可以添加路径
        re  正则表达式 
        
    2.第三方模块
        非Python本身自带的库,就是所谓的第三方的库
            
    3.模块的导入
        import xxx  [as  yy]
        from ../xx  import  xx  [as  yy]  
            
    4.自定义模块
        py文件,可以做为一个模块来用,直接作为一个模块导入就行
        __main__ 的意义:
            当文件是直接运行是,文件的__name__是__main__ ,当文件是被导入时,__name__是文件名
    
    5.包管理
        基本上就是另外一类模块。把用来处理一类事物的多个文件放在同一文件夹下组成的模块集。
        要让python 将其作为包对待,在python2中必须包含__init__.py的文件,但在python3中没有__init__.py文件也可以,使用包可以避免多个文件重名的情况,不同的包下的文件同名不影响。
            
        导入包和模块是一样的方法,包导入后会在目录中自动生成__pycache__文件夹存放生成的.pyc文件,要注意的是import后面的才是存在当前作用域中的对象名,from是告诉python从什么地方导入,
        使用sys.path添加文件的目录路径。
    #模块和包
    ##import keyword  #内置模块
    ##keyword.kwlist
    
    #模块就是一个py文件
    ##from keyword import kwlist as yy #导入你需要的
    from keyword import kwlist,main
    
    
    #同目录下
    import test
    __name__
    
    
    #不同路径下
    import os,sys
    
    sys.path
    sys.path.append(r'C:Users不动DesktopPython基础4面向对象2多继承,类的特殊方法,装饰器')
    
    import test1
    ##from test1 import ...
    
    if __name__ == '__main__':
        print(__name__)
        sys.argv
        print(sys.argv)
    ##    print('******',sys.argv[1])
    
    #
    #包就是把很多模块放在一起
    ##import xml
    ##import xml.dom.xmlbuilder

    3.作业

    1.利用列表推导式: 找出100以内所有奇数,并将所有奇数乘以3,写入列表。

    li =[i*3 for i in range(101) if i%2 !=0]
    li2 =[i*3 for i in range(101) if i%2 ==1]
    View Code

    2.在一个模块中定义一个用生成器,这个生成器可以生成斐波拉契数列,再另一个模块中使用这个生成器,得到斐波拉契数列

    '''
    def fab(num):
        n,a,b = 0,0,1
        while n < num:
            print(b)
            if n%10 ==0:
                yield b  #暂停
            a,b = b,a+b
            n +=1
    
    '''
    #同一个目录
    import fab
    
    
    #不是一个目录
    import os,sys
    sys.path.append(r'C:Users不动Desktop11')
    View Code
  • 相关阅读:
    Oracle创建表空间、创建用户以及授权、查看权限
    Oracle建立表空间和用户
    Oracle创建用户、表空间、导入导出、...命令
    C#中AppDomain.CurrentDomain.BaseDirectory与Application.StartupPath的区别
    maven 工程启动找不到 Spring ContextLoaderListener 的解决办法
    配置整合DWR3.0和Spring2.5使用annotation注解
    jQuery打印
    个项目涉及到的50个Sql语句(整理版)
    编写安卓平台程序的几种方式
    豪总说
  • 原文地址:https://www.cnblogs.com/woaixuexi9999/p/9215686.html
Copyright © 2011-2022 走看看