• python 全栈开发,Day8(文件操作)


    一、文件操作流程

    文件以什么编码存储的,就以什么编码打开

    参数:

    1.文件路径

    2.编码方式,encode

    3.执行动作(打开方式):只读,只写,追加,读写,写读...

    打开一个已经存在的文件

    f = open('D:qycache飞碟说.txt',encoding='utf-8',mode='r')
    content = f.read()
    print(content)
    f.close()
    

    执行输出:

    知识从未如此性感

    代码解释:

    变量,可以命令为f_obj,file,f_handler... 这个变量,称之为文件句柄(句柄是操作系统在生成对象时分配给对象的唯一标识)

    open  windows的系统功能,也就是说open这个命令,其实就是调用系统打开文件的动作

    windows 默认的编码方式:gbk,linux默认的编码方式为utf-8

    f.close()  关闭文件

    操作文件流程:

    打开一个文件,产生一个文件句柄,对文件句柄进行操作,关闭文件

    读:

    r 只读,以str方式读取

    rb 只读,以bytes类型读取(在非文字类的文件是,用rb。比如音频文件等)

    下面一个例子

    f = open('D:qycache飞碟说.txt',encoding='utf-8')
    content = f.read()
    print(content)
    f.close()
    

    默认mode不写,表示只读模式。

    编码不一致是,报错

    UnicodeDecodeError: 'gbk' codec can't decode byte 0xaa in position 14: illegal multibyte sequence

    所以,文件以什么编码存储的,就以什么编码打开

    二、文件路径

    绝对路径:从根目录开始,一级一级查找知道找到文件。 比如 D:qycache飞碟说.txt
    相对路径:在同一个文件夹下,直接写文件名即可。

    相对路径举例:

    f = open('天气.txt',encoding='utf-8')
    content = f.read()
    print(content)
    f.close()
    

    务必保证python代码和txt文件在同一文件夹下。

    某些windows系统,读取文件的时候报错

    [Error 22] Invalid argument: 'u202adD:\xx.txt'

    解决办法:

    1.加2个斜杠,比如 D:\xx.txt 

    2.前面加r ,比如 r'D:xx.txt'

    三、文件读取的5种模式

    r模式有5种模式读取

    第一种:全部读取出来 f.read()

    f = open('天气.txt',encoding='utf-8')
    content = f.read()
    print(content)
    f.close()
    

    执行输出:

    03月27日(今天)
    晴转多云
    11~27℃
    西南风 1级
    重度污染

    第二种:一行一行的读 f.readline()

    f = open('天气.txt',encoding='utf-8')
    print(f.readline())
    print(f.readline())
    print(f.readline())
    f.close()
    

    第三种:将原文件的每一行作为一个列表的元素 f.readlines()

    f = open('天气.txt',encoding='utf-8')
    print(f.readlines())
    f.close()
    

    执行输出:

    ['03月27日(今天) ', '晴转多云 ', '11~27℃ ', '西南风 1级 ', '重度污染']

    第四种:读取一部分 f.read(n)

    在r模式下,read(n) 按照字符去读取

    f = open('天气.txt',encoding='utf-8')
    print(f.read(3))
    f.close()
    

    执行输出:

    03月

    0 3 月   表示3个字符

    第五种:for循环读取

    f = open('天气.txt',encoding='utf-8')
    for i in f:
        print(i.strip())
    f.close()
    

    执行输出:

    03月27日(今天)
    晴转多云
    11~27℃
    西南风 1级
    重度污染

    在for循环中,每次读取一行,结束之后,内存就释放了。所以在整个for循环个过程中,始终只占用了一行内容的内存。
    推荐使用第5种方式。

    四、写操作

     w 文件不存在时,创建一个文件写入内容

    有文件时,将原文件内容清空,再写入内容

    f = open('log.txt',encoding='utf-8',mode='w')
    f.write('人生苦短,我想学Python')
    f.close()
    

    wb 以bytes写入,写入的内容,必须要转换为bytes类型才可以

    f = open('log.txt',mode='wb')
    f.write('人生苦短,我想学Python'.encode(encoding="utf-8"))
    f.close()

      

    a  追加

    没有文件时,创建一个文件追加内容

    有文件时,直接追加内容

    f = open('log2.txt',encoding='utf-8',mode='a')
    f.write('666')
    f.close()

    r+ 读写,先读,后追加。

    错误的写法

    f = open('log.txt',encoding='utf-8',mode='r+')
    f.write('BBB')
    content = f.read()
    print(content)
    f.close()
    

     执行输出,内容是空的

    为什么呢?

    因为光标,默认是从0开始。只要进行一个动作,光标就会移动,包括读取。
    上面的代码写入时,光标移动到最后了。所以执行f.read()时,读取不到后面的内容了。

    r+ 一定要先读后写,否则会错乱或者读取不到内容

    w+ 先写后读

    f = open('log.txt',encoding='utf-8',mode='w+')
    f.write('AAA')
    content = f.read()
    print(content)
    f.close()
    

    执行输出,内容是空的

    写完之后,光标移动到最后了。所以读取的时候,读取不到内容了。

    f = open('log.txt',encoding='utf-8',mode='w+')
    f.write('AAA')
    print(f.tell()) #按直接去读光标位置
    f.seek(0) #调整光标位置
    content = f.read()
    print(content)
    f.close()
    

    执行输出:

    3
    AAA

    下面一个例子

    f = open('log.txt',encoding='utf-8',mode='w+')
    f.write('中国')
    print(f.tell()) #按直接去读光标位置
    f.seek(2) #调整光标位置
    content = f.read()
    print(content)
    f.close()
    

    执行输出:

    6

    .....

    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xad in position 0: invalid start byte

    因为一个中文占用3字节

    ftp的断点续传,需要用到光标,一定会用到tell和seek

    a+ 追加读

    这里不举例了

    上面列举了那么多模式

    用的最多的还是r和r+模式

    r的5种模式中,重点掌握第5种。

    其他操作方法:

    truncate #截取文件
    writable() #是否可写
    readable() #是否可读

    truncate是截取文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

    f = open('log.txt',encoding='utf-8',mode='r+')
    # 截取10个字节
    f.truncate(3)
    content = f.read()
    print(content)
    f.close()
    

    执行输出:

    判断是否可写

    f = open('log.txt',encoding='utf-8',mode='r+')
    print(f.writable())
    f.close()
    

    执行输出:

    True

    回收方法为:
    1、f.close() #回收操作系统级打开的文件,关闭文件句柄
    2、del f #回收应用程序级的变量,在python代码级别中,删除变量

    为了避免忘记回收文件句柄,需要使用with open方法,代码执行完毕之后,自动关闭文件句柄

    功能1:自动关闭文件句柄

    with open('log.txt',encoding='utf-8') as f:
        print(f.read())
    

    功能2:一次性操作多个文件

    with open('log.txt',encoding='utf-8') as f1,
        open('log1.txt',encoding='utf-8',mode='r+') as f2:
        print(f1.read())
        print(f2.read())
    

    有些情况下,必须先关闭,才能执行某某动作的情况下,不能用with,这种情况比较少见。

    推荐使用with open

    所有的软件,不是直接在原文件修改的。
    它是进行了5步操作

    1.将原文件读取到内存。
    2.在内存中进行修改,形成新的内容。
    3.将新的字符串写入新文件。
    4.将原文件删除。
    5.将新文件重命名成原文件。

    将log文件内容中含有张三的,替换为李四

    import os
    #第1步
    with open('log',encoding='utf-8') as f1,
        open('log.bak',encoding='utf-8',mode='w') as f2:
        content = f1.read()
        #第2步
        new_content = content.replace('张三','李四')
        #第3步
        f2.write(new_content)
    #第4步
    os.remove('log')
    #第5步
    os.rename('log.bak','log')
    

    这种方法,不好。如果文件比较大,内存直接爆掉。因为f1.read()是将文件所有内容写入内存中。

    推荐做法:

    import os
    #第1步
    with open('log',encoding='utf-8') as f1,
        open('log.bak',encoding='utf-8',mode='w') as f2:
        for i in f1:
            #第3步
            new_i = i.replace('张三', '李四')
            #第4步
            f2.write(new_i)
    #第4步
    os.remove('log')
    #第5步
    os.rename('log.bak','log')

    这种方式,每次只占用一行。
    所有软件,都是执行这5步的。

    课后作业:

    1. 文件a.txt内容:每一行内容分别为商品名字,价钱,个数。
    apple 10 3
    tesla 100000 1
    mac 3000 2
    lenovo 30000 3
    chicken 10 3
    通过代码,将其构建成这种数据类型:[{'name':'apple','price':10,'amount':3},{'name':'tesla','price':1000000,'amount':1}......] 并计算出总价钱。
    2,有如下文件:
    -------
    alex是老男孩python发起人,创建人。
    alex其实是人妖。
    谁说alex是sb?
    你们真逗,alex再牛逼,也掩饰不住资深屌丝的气质。
    ----------
    将文件中所有的alex都替换成大写的SB。
    
    
    
    
    3. 文件a1.txt内容:
    文件内容:
    name:apple price:10 amount:3 year:2012
    name:tesla price:100000 amount:1 year:2013
    
    通过代码,将其构建成这种数据类型:
    [{'name':'apple','price':10,'amount':3},
    {'name':'tesla','price':1000000,'amount':1}......]
    并计算出总价钱。
    4,文件a2.txt内容:
    文件内容:
    序号     部门      人数      平均年龄      备注
    1       python    30         26         单身狗
    2       Linux     26         30         没对象
    3       运营部     20         24         女生多
    通过代码,将其构建成这种数据类型:
    [{'序号':'1','部门':Python,'人数':30,'平均年龄':26,'备注':'单身狗'},
    ......]
    并计算出总价钱。
    5,明日默写:就是第二题的代码(课上讲过)。 

     答案:

    第一题

    1.1先将文件内容读取出来

    with open('a.txt',encoding='utf-8') as f:
        for i in f:
            i = i.strip()
            print(i)
    

    执行输出:

    apple 10 3
    tesla 100000 1
    mac 3000 2
    lenovo 30000 3
    chicken 10 3

    1.2使用空格切割成列表

    with open('a.txt',encoding='utf-8') as f:
        for i in f:
            i = i.strip().split()
            print(i)
    

    执行输出:

    ['apple', '10', '3']
    ['tesla', '100000', '1']
    ['mac', '3000', '2']
    ['lenovo', '30000', '3']
    ['chicken', '10', '3']

    1.3将列表的内容放入字典中,测试打印

    with open('a.txt',encoding='utf-8') as f:
        for i in f:
            i = i.strip().split()
            print({'name': i[0], 'price': i[1], 'amount': i[2]})
    

    执行输出:

    {'amount': '3', 'name': 'apple', 'price': '10'}
    {'amount': '1', 'name': 'tesla', 'price': '100000'}
    {'amount': '2', 'name': 'mac', 'price': '3000'}
    {'amount': '3', 'name': 'lenovo', 'price': '30000'}
    {'amount': '3', 'name': 'chicken', 'price': '10'}

    1.4 将字典追加到一个空列表中

    #总列表
    li = []
    with open('a.txt',encoding='utf-8') as f:
        for i in f:
            #默认使用空格分割
            i = i.strip().split()
            #将字典追加到列表中
            li.append({'name': i[0], 'price': i[1], 'amount': i[2]})
    
    print(li)
    

    执行输出:

    [{'price': '10', 'name': 'apple', 'amount': '3'}, {'price': '100000', 'name': 'tesla', 'amount': '1'}, {'price': '3000', 'name': 'mac', 'amount': '2'}, {'price': '30000', 'name': 'lenovo', 'amount': '3'}, {'price': '10', 'name': 'chicken', 'amount': '3'}]

    1.5 计算总价格,最终完整代码如下:

    #总列表
    li = []
    #总价格
    the_sum = 0
    with open('a.txt',encoding='utf-8') as f:
        for i in f:
            #默认使用空格分割
            i = i.strip().split()
            #将字典追加到列表中
            li.append({'name': i[0], 'price': i[1], 'amount': i[2]})
    
    #遍历列表
    for i in li:
        #计算总价格(单价*个数)
        the_sum += int(i['price']) * int(i['amount'])
    
    print(li)
    print('总价钱为: {}'.format(the_sum))

    执行输出:

    [{'amount': '3', 'name': 'apple', 'price': '10'}, {'amount': '1', 'name': 'tesla', 'price': '100000'}, {'amount': '2', 'name': 'mac', 'price': '3000'}, {'amount': '3', 'name': 'lenovo', 'price': '30000'}, {'amount': '3', 'name': 'chicken', 'price': '10'}]
    总价钱为: 196060

    老师的代码:

    li = []
    the_sum = 0
    name_list = ['name','price','amount','year']
    with open('a.txt',encoding='utf-8') as f1:
        for i in f1:
            l2 = i.strip().split()
            dic = {}
            for j in range(len(l2)):
                dic[name_list[j]] = l2[j]
            li.append(dic)
    #遍历列表
    for i in li:
        #计算总价格(单价*个数)
        the_sum += int(i['price']) * int(i['amount'])
    
    print(li)
    print('总价钱为: {}'.format(the_sum))
    

    执行效果同上

    第2题,老师讲过,直接贴代码:

    import os
    with open('log.txt',encoding='utf-8') as f1,
        open('log.bak',encoding='utf-8',mode='w') as f2:
        for i in f1:
            new_i = i.replace('alex', 'SB')
            f2.write(new_i)
    
    os.remove('log.txt')
    os.rename('log.bak','log.txt')
    

    执行代码,查看文件内容如下:

    SB是老男孩python发起人,创建人。
    SB其实是人妖。
    谁说SB是sb?
    你们真逗,SB再牛逼,也掩饰不住资深屌丝的气质。

    第3题,和第1题类似

    3.1直接读取文件,并取出对应的值

    with open('log.txt', encoding='utf-8') as f:
        for i in f:
            # 默认使用空格分割
            i = i.strip().split()
            #使用冒号切割,获取value
            name = i[0].split(':')[1]
            price = i[1].split(':')[1]
            amount = i[2].split(':')[1]
            year = i[3].split(':')[1]
            print(name,price,amount,year)
    

    执行输出:

    apple 10 3 2012
    tesla 100000 1 2013

    3.2将取出的内容写入字典中,并追加到总列表里面

    # 总列表
    li = []
    with open('log.txt', encoding='utf-8') as f:
        for i in f:
            # 默认使用空格分割
            i = i.strip().split()
            #使用冒号切割,获取value
            name = i[0].split(':')[1]
            price = i[1].split(':')[1]
            amount = i[2].split(':')[1]
            year = i[3].split(':')[1]
            #将字典追加到列表中
            li.append({'name':name, 'price': price, 'amount': amount,'year':year})
    
    print(li)
    

    执行输出:

    [{'name': 'apple', 'price': '10', 'year': '2012', 'amount': '3'}, {'name': 'tesla', 'price': '100000', 'year': '2013', 'amount': '1'}]

    3.3遍历总列表,计算总价钱,最终代码如下

    # 总列表
    li = []
    # 总价钱
    the_sum = 0
    with open('log.txt', encoding='utf-8') as f:
        for i in f:
            # 默认使用空格分割
            i = i.strip().split()
            # 使用冒号切割,获取value
            name = i[0].split(':')[1]
            price = i[1].split(':')[1]
            amount = i[2].split(':')[1]
            year = i[3].split(':')[1]
            # 将字典追加到列表中
            li.append({'name': name, 'price': price, 'amount': amount, 'year': year})
    
    # 遍历总列表
    for i in li:
        # 计算总价钱(单价*个数)
        the_sum += int(i['price']) * int(i['amount'])
    
    print(li)
    print('总价钱为: {}'.format(the_sum))

    执行输出:

    [{'year': '2012', 'amount': '3', 'price': '10', 'name': 'apple'}, {'year': '2013', 'amount': '1', 'price': '100000', 'name': 'tesla'}]
    总价钱为: 100030

    老师的代码:可扩展性强,不论是横排还是竖排增加数据,都是适用

    l1 = []
    the_sum = 0
    with open('a1.txt',encoding='utf-8') as f1:
        for i in f1:
            li = i.strip().split()
            dic = {}
            for j in li:
                #使用冒号切割字符串,转成列表
                l2 = j.strip().split(':')
                #添加字典,l2[0]表示key,l2[1] 表示value
                dic[l2[0]] = l2[1]
            #将字典追加到列表中
            l1.append(dic)
    
    # 遍历总列表
    for i in l1:
        # 计算总价钱(单价*个数)
        the_sum += int(i['price']) * int(i['amount'])
    
    print(l1)
    print('总价钱为: {}'.format(the_sum))
    

      执行输出,效果同上。

    第4题

    4.1 先读取文件内容

    with open('log.txt', encoding='utf-8') as f:
        for i in f:
            i = i.strip()
            print(i)
    

    执行输出:

    序号 部门 人数 平均年龄 备注
    1 python 30 26 单身狗
    2 Linux 26 30 没对象
    3 运营部 20 24 女生多

    4.2 我需要第一行内容(序号 部门 人数 平均年龄 备注),作为标题栏,放入列表中

    #行数
    line_num = 0
    with open('log.txt', encoding='utf-8') as f:
        for i in f:
            i = i.strip()
            #行数加1
            line_num += 1
            #判断行数是否等于1
            if (line_num == 1):
                #去除空格,使用空格切割
                title = i.strip().split()
                #加入标题的列表中
                title_bar = [title[0],title[1],title[2],title[3],title[4]]
    
    print(title_bar)

    执行输出:

    ['序号', '部门', '人数', '平均年龄', '备注']

    4.3 将(序号 部门 人数 平均年龄 备注)里面的内容提取出来

    #行数
    line_num = 0
    with open('log.txt', encoding='utf-8') as f:
        for i in f:
            i = i.strip()
            #行数加1
            line_num += 1
            #判断行数是否等于1
            if (line_num == 1):
                #去除空格,使用空格切割
                title = i.strip().split()
                #加入标题的列表中
                title_bar = [title[0],title[1],title[2],title[3],title[4]]
            else:
                #切割数据
                split_data = i.strip().split()
                #序号
                id = split_data[0]
                #部门
                department = split_data[1]
                #人数
                number = split_data[2]
                #平均年龄
                average_age = split_data[3]
                #备注
                remarks = split_data[4]
                #打印结果
                print(id,department,number,average_age,remarks)
    

    执行输出:

    1 python 30 26 单身狗
    2 Linux 26 30 没对象
    3 运营部 20 24 女生多

    4.4将最后一行代码print改成字典输出

    #行数
    line_num = 0
    li = []
    with open('log.txt', encoding='utf-8') as f:
        for i in f:
            i = i.strip()
            #行数加1
            line_num += 1
            #判断行数是否等于1
            if (line_num == 1):
                #去除空格,使用空格切割
                title = i.strip().split()
                #加入标题的列表中
                title_bar = [title[0],title[1],title[2],title[3],title[4]]
            else:
                #切割数据
                split_data = i.strip().split()
                #序号
                id = split_data[0]
                #部门
                department = split_data[1]
                #人数
                number = split_data[2]
                #平均年龄
                average_age = split_data[3]
                #备注
                remarks = split_data[4]
                #打印结果
                print({title_bar[0]:id,title_bar[1]:department,title_bar[2]:number,title_bar[3]:average_age,title_bar[4]:remarks})
    

    执行输出:

    {'人数': '30', '备注': '单身狗', '序号': '1', '平均年龄': '26', '部门': 'python'}
    {'人数': '26', '备注': '没对象', '序号': '2', '平均年龄': '30', '部门': 'Linux'}
    {'人数': '20', '备注': '女生多', '序号': '3', '平均年龄': '24', '部门': '运营部'}

    4.5将打印的字典,添加到总列表中,最终代码如下

    #行数
    line_num = 0
    #总列表
    li = []
    with open('log.txt', encoding='utf-8') as f:
        for i in f:
            i = i.strip()
            #行数加1
            line_num += 1
            #判断行数是否等于1
            if (line_num == 1):
                #去除空格,使用空格切割
                title = i.strip().split()
                #加入标题的列表中
                title_bar = [title[0],title[1],title[2],title[3],title[4]]
            else:
                #切割数据
                split_data = i.strip().split()
                #序号
                id = split_data[0]
                #部门
                department = split_data[1]
                #人数
                number = split_data[2]
                #平均年龄
                average_age = split_data[3]
                #备注
                remarks = split_data[4]
                #将字典添加到列表中
                li.append({title_bar[0]:id,title_bar[1]:department,title_bar[2]:number,title_bar[3]:average_age,title_bar[4]:remarks})
    
    print(li)
    

    执行输出:

    [{'备注': '单身狗', '平均年龄': '26', '人数': '30', '序号': '1', '部门': 'python'}, {'备注': '没对象', '平均年龄': '30', '人数': '26', '序号': '2', '部门': 'Linux'}, {'备注': '女生多', '平均年龄': '24', '人数': '20', '序号': '3', '部门': '运营部'}]

    老师的代码:可扩展性强,不论是横排还是竖排增加数据,都是适用

    l1 = []
    with open('a2.txt',encoding='utf-8') as f1:
        #读取第一行,去除空格,使用空格切割成列表
        list_name = f1.readline().strip().split()
        #从第二行开始读取,因为读取一行之后,光标自动移动到下面一行。
        #所以for循环不会读取到第一行
        for i in f1:
            dic = {}
            #去除空格,以空格切割成列表
            i = i.strip().split()
            #遍历i
            for j in range(len(i)):
                #添加字典, list_name[j]表示key, i[j]表示value,比如'序号': '1'
                dic[list_name[j]] = i[j]
            #添加到列表中
            l1.append(dic)
    
    print(l1)
    

    执行效果同上

  • 相关阅读:
    save html to local
    Django REST framework¶
    a colorful termial output for phantomjs porting from casperjs
    jespern / djangopiston / wiki / Documentation — Bitbucket
    PyKHTML, a Python interface to KHTML
    phantomjs/examples/echoToFile.js at master · ariya/phantomjs
    Scraping multiple sites in parallel and memory consumption Google Groups
    jQuery Arrays | Create, Add To, Remove From and Compare
    They're hiring based on New Brunswick, NJ, USA
    FudanNLP  java based
  • 原文地址:https://www.cnblogs.com/xiao987334176/p/8657888.html
Copyright © 2020-2023  润新知