美文网首页
Python基础总结--10(模块使用、迭代器、生成器、文件)

Python基础总结--10(模块使用、迭代器、生成器、文件)

作者: zxhlcl | 来源:发表于2018-10-13 15:29 被阅读0次

    一、模块使用

    模块就是用一堆代码实现了某个功能的代码集合,python中一个py文件就是一个模块;模块有三种类型:自定义模块,内置模块,第三方模块
    1、自定义一个模块

    ''' 自定义了一个my_math 模块 '''
    PI=3.14159
    e=2.718
    def fibo(n):
        if n==1 or n==0:return 1
        return fibo(n-1)+fibo(n-2)
    
    def factorial(n:int):
        result=1
        for x in range(1,n+1):
            result*=x
        return result
    
    if __name__=="__main__":
        print(PI )
        print(fibo(10))
        print(factorial(5))
    #执行该模块后的结果:
    '''
    3.14159
    89
    120
    '''
    

    注意:
    若模块中存在 if name == 'main':
    直接执行当前模块,代码块会被执行;如果在别的模块中被导入,代码块不会执行(阻止其他模式使用该模块的代码)
    分析:
    每一个模块都有一个_ _name_ _属性, 这个属性的默认值是当前模块对应py文件的文件名;当当前模块正被执行(直接)的时候,系统会自动将模块的_ _name_ _属性变成'_ _main_ _'
    2、模块的使用
    导入模块:代码执行到import的时候,会将import后面的模块的内容执行一遍;当两个模块中含有相同名称函数或者变量的时候,后面一次引入会覆盖前一次引入
    (1)import 模块名
    将模块中所有的内容都导入,并且可以在当前模块中通过'模块名.'的方式去使用模块中的所有全局变量
    (2)from 模块名 import 变量1, 变量2,
    将模块中所有的内容都导入,但是只能使用import后面的变量
    注意:通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名
    (3)from 模块名 import *
    将模块中所有的内容都导入, 可以直接使用模块中的所有全局变量
    重命名:
    (1)import 模块名 as 模块的新名字
    给模块重命名,使用模块的时候用新的名字来使用
    (2)from 模块名 import 变量名1 as 新名1, 变量名2
    给部分变量重新命名

    import my_math as Math_mine
    print(Math_mine.e,Math_mine.PI)
    from my_math import *
    print(fibo(10))
    from my_math import PI as pi,e as E
    print(pi,E)
    

    二、迭代器

    什么是迭代器
    1.什么是迭代器(iter)
    迭代器是python中一种容器类的数据类型,属于序列。没有具体的字面量,可以将其他的序列转换成迭代器:iter(序列)
    2.迭代器的特点
    只能通过next方法去一个一个按顺序获取迭代器中的元素,取出后迭代器中就不存在这个元素了

    任何实现了iternext()方法的对象都是迭代器,iter返回迭代器自身,next返回容器中的下一个值;如果容器中没有更多元素了,则抛出StopIteration异常
    迭代器的使用

    iter1 = iter('abcd')
    print(iter1) #返回一个迭代器对象
    print(next(iter1)) #获取迭代器的值
    print(next(iter1))
    iter2 = iter((1, 2, 3))
    a = iter2.__next__()  #通过.__next__()方法
    print(a)  # 1
    list1 = list(iter2)
    print(list1)  # [2, 3]
    #遍历迭代器
    iter1 = iter(['abc', 10, 'name'])
    print('=====')
    for x in iter1:
        print(x)
    print('====')
    

    小结:
    凡是可作用于for循环的对象都是Iterable类型;
    凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
    集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
    Python的for循环本质上就是通过不断调用next()函数实现的

    三、生成器

    生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅,实质就是函数体中有yield关键字的函数
    生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值
    从列表推导式说起....
    若一个列表为:[1,2,3,4,5,6,7,8,9],要求把每一个元素都翻倍,实现的方式有三种:

    #第一种:使用循环
    info = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    for index,element in enumerate(info):
        info[index] *=2
    print(info)
    #enumerate()--将一个可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标
    
    #第二种:使用map()函数
    info = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    a = map(lambda x:x*2,info)
    for i in a:
        print(i,end=" ")
    
    #第三种:使用列表推导式
    info = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    a = [i*2 for i in range(10)]
    print(a)
    

    思考:
    若列表的数据很大(1000万个元素),创建的时候占用了大量的内存空间,但是又只需要用到前面1000个元,那后面绝大多数元素占用的空间都白白浪费了
    所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator
    生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器
    生成器与一般函数的不同:
    (1)生成器函数包含一个或者多个yield
    (2)当调用生成器函数时,函数将返回一个对象,但是不会立刻向下执行
    (3)像iter()和next()方法等是自动实现的,可以通过next()方法对对象进行迭代
    (4)一旦函数被yield,函数会暂停,控制权返回调用者
    (5)局部变量和它们的状态会被保存,直到下一次调用
    (6)函数终止的时候,StopIteraion会被自动抛出

    生成式
    生成式就是生成器的一种特殊形式:(变量 for 变量 in 序列)

    gen1 = (x*2 for x in range(5))
    print('=========')
    for item in gen1:
        print(item)
    gen2 = ([x, x*2] for x in 'abc')
    print(next(gen2))
    print('===========')
    gen3 = (x for x in range(5) if x%2)
    for item in gen3:
        print(item)
    

    生成器函数
    也是用def定义的,利用关键字yield一次性返回一个结果,阻塞,重新开始

    def gen4(n):
        for x in range(n+1):
            print("第{}次循环:x={}".format(x,x))
            yield x
            if x % 2 :
                yield "{}是奇数".format(x)
            else:
                yield "{}是偶数".format(x)
    a=gen4(5) 
    print(a) #<generator object gen4 at 0x0000021D15D6D678>
    print(a.__next__())  #执行到yield关键字,控制权返回调用者,并保持局部变量状态
    print(a.__next__())  #从yield关键字开始继续执行,遇到yield关键字再次返回
    '''
    第0次循环:x=0
    0
    0是偶数
    '''
    def gen5(n):
        for x in range(n):
            yield x, 2*x, 3*x
        return "Done"
    a=gen5(3)
    print(next(a))
    print(next(a))
    print(next(a))
    '''
    (0, 0, 0)
    (1, 2, 3)
    (2, 4, 6)
    '''
    #思考:如何才能取到返回值Done?
    #必须捕获StopIteration错误,返回值包含在StopIteration的value
    while True:
        try:
            x=next(a)
            print('generator: ',x)
        except StopIteration as e:
            print("生成器返回值:",e.value)  #生成器返回值: Done
            break
    
    #用生成器计算斐波拉契数列
    def fibo(max):
        n,a,b =0,0,1
        while n < max:
            yield b
            a,b =b,a+b
            n = n+1
        return 'done'
    for i in fibo(6):
        print(i,end=",")
    #创建一个generator后,基本上永远不会调用next(),而是通过for循环来迭代,并且不需要关心StopIteration的错误
    

    四、文件操作

    使用文件可以做数据的持久化(本地化) ---> 数据库文件,txt、json,plist,二进制文件
    所有文件操作的过程:打开文件 --> 操作文件 --> 关闭文件
    文件操作 -- 读写操作
       读 -> 取出文件中的数据
       写 -> 将数据写到文件中
    打开文件和关闭文件
    open(file, mode='r',encoding=None)
    a.file -> 文件路径(必须传参),决定需要打开的是哪个文件
    绝对路径(不推荐使用)
    相对路径: ./相对路径 (相对路径是相对当前py文件对应的文件夹)
         ./ ---> 当前文件夹
          ../ --> 当前文件夹的上层文件夹
         .../ --> 当前文件夹的上层文件夹的上层文件夹
    b.mode -> 文件打开方式(不同的操作对应不同的打开方式)
         'r' --> 以只读的形式打开文件, 文本
         'rb'/'br' --> 读操作,读出来的数据是二进制形式的数据
         'w' --> 以写的形式打开文件(完全覆盖)
         'bw'/'wb' --> 写操作,将二进制数据写入文件
         'a' --> 写操作,追加
    c.encoding -> 文本文件的编码方式
        utf-8 :几乎支持所有的语言文字
        gbk : 只支持英文

    d.open函数的返回值,就被打开的文件对象

    关闭文件: 文件对象.close()

    f1 = open('./test1.txt', 'r', encoding='utf-8')
    content = f1.read()
    print(type(content), content)
    content = f1.readline()  
    print(type(content), content)# #<class 'str'> 返回值为空,该文件打开后已经被读完
    content = f1.readlines()
    print(type(content), content) #<class 'list'> []
    f1.close()
    
    
    f2 = open('./test1.txt', 'w', encoding='utf-8')
    f2.writelines(['abc\n', '123\n', 'aaaaa\n'])
    

    with关键字
    with open(文件路径,打开方式,encoding=编码方式) as 文件对象:
    文件操作代码
    说明:打开文件执行操作后自动关闭文件对象,防止操作过程中出现异常导致文件未关闭

    with open("./file/libai.txt",'w',encoding='utf-8') as file1:
        file1.write('床前明月光,\n疑是地上霜\n')
    with open("./file/libai.txt",'r',encoding='utf-8') as file1:
        content=file1.read()
        print(content)
    

    二进制文件操作
    常见的二进制文件:视频、音频、图片、压缩包等
    bytes -->字节,python专门用来表示二进制数据类型
    注意:二进制文件不能设置文件编码方法(不能给encoding赋值)
    作用:下载或上传文件

    with open('./file/chengfabiao.png','rb') as file2:
        content=file2.read()
        print(type(content),content)
    with open('./file/chengfabiao_copy.png','wb') as file2:
        file2.write(content)
    

    思考:读取或写入数据量为10G的文件,如何做?

    相关文章

      网友评论

          本文标题:Python基础总结--10(模块使用、迭代器、生成器、文件)

          本文链接:https://www.haomeiwen.com/subject/aiqoaftx.html