美文网首页python自动化测试
python自动化测试 第 5 章.文件操作

python自动化测试 第 5 章.文件操作

作者: 失忆的蝴蝶 | 来源:发表于2021-11-15 20:08 被阅读0次

    一、文件概述

    1. 什么是文件

    计算机文件是一个存储在存储器上的数据的序列,可以包含任意的数据内容。

    • 文本文件 有统一的字符编码
    • 二进制文件 字符编码不统一(如:图片、视频文件等)

    2. 字符编码

    一个一个的小图片,字体文件 包含了这个字体类型的所有文字的图片。再给每个字符一个编号,
    存储的时候,存这个编号。这个编号标就是字符编码。

    2.1 ascii码

    在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码,统一规定了上述常用符号用哪些二进制数来表示
    ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符

    image.png
    1Byte = 8bit
    1Kb = 1024B
    1Mb = 1024Kb
    1Gb = 1024Mb
    1Tb = 1024Gb
    一个字节 = 8位 8位二进制 0-255
    一个ASCII码占用存储空间为1个字节
    10000个ASCII码占用的内存大小为:10000 /1024 Kb

    2.2 gb2312

    ASCII不支持中文,为了支持计算机使用中文,推出gb2312.

    GB2312编码适用于汉字处理、汉字通信等系统之间的信息交换,通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB 2312。
    基本集共收入汉字6763个和非汉字图形字符682个。

    0-6763

    2个字节来表示一个汉字

    10000个中文所占的内存大小:10000*2B/1024

    向上兼容ascii

    2.3 gbk

    GBK是GB2312的扩展,因为GB2312有些生僻字无法识别,所以开发了GBK编码,K就是扩展的意思
    GBK 采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。
    2个字节表示一个汉字
    向上兼容ascii

    print('囙'.encode('gbk')) # 输出b'\x87\xe0'
    print('囙'.encode('gb2312')) # 会报错
    

    2.4 unicode

    把世界上所有主流的编码都收纳进来。10w+
    4个字节来表示一个字符
    缺点:太大了,且内存变大
    python3在内存里使用unicode

    2.5 utf-8

    根据字符编号动态的选择大小。
    ascii 1个字节
    中文 3个字节
    UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码。它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部分修改后,便可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。

    ANSI码是指电脑用什么编码就用什么编码

    3. 信息量

    bit,一个位,表示一个二进制数 0,1

    8bit叫一个Byte(字节)2的八次方 256

    • 1024B = 1KB
    • 1024KB = 1MB
    • 1024MB = 1GB
    • 1024GB = 1TB

    0-255 之间的整数

    4. 字节类型

    Bytes表示二进制信息,它由单个字节构成的不可变序列。

    字面量语法与字符串相似,加了一个前导符‘b’

    只允许有ascii

    超过了127的二进制值,使用十六进制来表示。

    字符转换为对应的编码称为编码 A -> b'\x41'

    根据字符编码转换为字符称为解码 b'\x41' -> A 解码

    # ascii码字符编码,使用本身字母的字面量来表示。
    res = 'abc123'.encode('ascii')
    print(res, type(res))  # 输出b'abc123'
    
    # gbk 用两个字节表示一个汉字,utf-8使用3个字节表示一个汉字
    print('中'.encode('gbk'), type('中'.encode('gbk')))  # 输出b'\xd6\xd0'
    print('中'.encode('utf-8'), type('中'.encode('utf-8')))  # 输出b'\xe4\xb8\xad'
    
    # 解密
    print(b'\xd6\xd0'.decode('gbk')) # 输出"中"
    # 中‘’字在gbk编码中编码为54992
    print(bin(54992))
    print(hex(0b11010110))
    

    不是所有的二进制信息都可以解码为字符。

    用不一致的解码方式去打开对应的文件,会出现乱码:
    notepad++打开一个记事本文件--编码--选择日文,并粘贴日文到记事本中--再使用其他编码方式,此时日文会变成乱码


    image.png

    二、python操作文件

      1. 打开文件
      1. 操作文件 (读 写)
      1. 关闭文件

    1. open函数

    open(file, mode='r', encoding=None)

    mode的取值:

    字符 意义
    'r' 文本读取(默认)
    'w' 文本写入,并先清空文件(慎用),文件不存在则创建
    'x' 文本写,排它性创建,如果文件已存在则失败
    'a' 文本写,如果文件存在则在末尾追加,不存在则创建

    mode组合的字符

    字符 意义
    'b' 二进制模式,例如:'rb'表示二进制读
    't' 文本模式(默认),例如:rt一般省略t
    '+' 读取与写入,例如:'r+' 表示同时读写

    2.读文本文件

    在当前目录下创建一个名为 test.txt 的文本文件,(注意编码方式)文件中写入下面的内容:

    静夜思
    床前明月光,疑是地上霜。
    举头望明月,低头思故乡。
    

    2.1 操作基本步骤

    # 打开文件 mode=rt,t可以省略
    fb = open('test.txt', 'r', encoding='utf-8')
    # 读取
    content = fb.read()
    print(content)
    # 关闭文件
    fb.close()
    

    这种操作经常会忘记关闭文件句柄,造成资源浪费,所以处理文件是往往使用 with 语句进行上下文管理。
    上面中的fb是文件句柄,通过fb去调用这个问题
    何为句柄?
    后面学习会遇到文件句柄、窗口句柄,下面是摘取一些网上的见解
    句柄可以理解为就是一个id或者编码,可以凭借这个id对文件或者窗口进行标识了。
    举例:就和你去饭店吃饭要排队,前台小姐给你分配了一个编号一样,然后她可以通过编号找到你。

    在操作系统或者某种其他编程系统中,句柄就是这样的一个编号,用来对各种奇奇怪怪的东西编号,系统对你来说是一个黑箱,你只能通过这个编号向系统要东西。
    句柄就是将直接调用改为间接调用,以避免每次调用的时候在库里搜寻,提高调用速度

    2.2 with 上下文管理

    with open('test.txt', 'r', encoding='utf-8') as fb:
        content = fb.read()
        print(content)
    

    with 语句执行完毕会自动关闭文件句柄。

    2.3 逐行读取

    • read上面所使用的read会把文本的内容全部返回,很多时候会造成内存一下子变太大,而且有些数据不需要使用的,也会降低效率。下面介绍逐行读取文本内容的方法

    在读取文本文件时,经常需要按行读取,文件对象提供了多种方法进行按行读取。

    2.3.1readline

    从文件中读取一行;如果 f.readline() 返回一个空的字符串,则表示已经到达了文件末尾

    with open('test.txt', 'r', encoding='utf-8') as fb:
        print(fb.readline())
        print(fb.readline())
        print(fb.readline())
        print(fb.readline())
    

    2.3.2readlines

    以列表的形式返回文件中所有的行。

    with open('test.txt', 'r', encoding='utf-8') as fb:
        content = fb.readlines()
        print(content)
    

    2.3.3 迭代(推荐使用此方法)

    要从文件中读取行,还可以循环遍历文件对象。这是内存高效,快速的,并简化代码:

    with open('test.txt', 'r', encoding='utf-8') as fb:
        for line in fb:
            print(line)
    

    2.4 相对路径与绝对路径

    绝对路径

    绝对路径是指定了文件在电脑中的具体位置,以 windows 电脑为例:

    D:\Pycharm_workspace\day12file\读文本.py
    

    相对路径

    相对路径一般是指相对当前脚本的路径,比如上面的案例中的 test.txt 因为和当前脚本在同一个文件夹下,所以可以直接使用 test.txt 作为文件名来操作。
    也可显式地表达当前路径 ./test.txt,
    ./ 表示当前目录
    ../ 表示上级目录,同理 ../../ 表示上上级目录,依此类推。

    使用场景

    相对路径:一般情况下项目本身的资源文件和脚本路径相对固定,为了不影响项目的移植性,必须使用相对路径。
    相对路径:需要读取操作系统中固定位置的系统文件一般使用绝对路径。

    3.读二进制文件

    任何文件都可以以二进制读的方式打开,读取 test.txt 的二进制内容。
    ** 读取二进制文件时(也就是mode=rb时),不需要encoding参数**

    # mode=rb,不需要encoding参数
    with open('test.txt', 'rb') as fb:
        content = fb.read()
        print(content)
    
    # 也可以逐行读取,以\n换行符标志
    with open('test.txt', 'rb') as fb:
        for line in fb:
            print(line)
    

    4. 写文本文件

    4.1 清除写 w

    mode=w 没有文件就创建,有就清除内容,小心使用

    with open('test.txt', 'w', encoding='utf-8') as fb:
        fb.write('锄禾\n')
        fb.write('锄禾日当午,汗滴禾下土;\n')
        fb.write('谁知盘中餐,粒粒皆辛苦。\n')
    

    4.2 追加写 a

    mode=a 追加到文件的最后

    # mode=a 追加到文件的最后
    with open('test.txt', 'a', encoding='utf-8') as fb:
        fb.write('静夜思\n床前明月光,疑是地上霜;\n举头望明月,低头思故乡。\n')
    

    4.3 排他写 x

    在当前目录中创建文件 test.txt,存在则不创建,且会报错

    with open('test2.txt', 'x', encoding='utf-8') as fb:
        fb.write('1天空之城1')
    

    FileExistsError: [Errno 17] File exists: 'test2.txt'

    5.写二进制文件

    在写模式后加 b 即是写二进制模式,这种模式下写入内容为字节数据。

    例如:将爬到的图片二进制信息写入文件中。

    import requests
    
    url = 'https://pic.netbian.com/uploads/allimg/211115/232008-1636989608f1ca.jpg'
    response = requests.get(url)
    # print(response.content) # 打印出图片的二进制信息
    with open('美女壁纸.jpg', 'wb') as f:
        f.write(response.content)
    

    6.读写文件

    有时候需要能够同时读写文件,在模式后面加上 + 号即可给读模式添加写,给写模式添加读

    7.案例:python 处理解析 CSV 文件

    读取csv文件并解析为嵌套列表
    方法一:
    实现思路:用readlines把列表的形式返回文件中所有的行,但是此时各个元素的末端有回车,利用for循环获取到每个元素,strip()把回车符去掉,再把每个元素(字符串)转换成列表

    with open('鸢尾.csv', 'r', encoding='gbk') as fb:
        content = fb.readlines()
    
        for i in range(len(content)):
            content[i] = content[i].strip()
            content[i] = content[i].split(',')
    

    方法二(推荐):

    data = []
    with open('鸢尾.csv', 'r', encoding='gbk') as fb:
    
        for line in fb:
            # 去掉每行末端的回车
            line = line.strip()
            data.append(line.split(','))
        print(data)
    
    # 将数据写为csv文件
    with open('test.csv', 'w', encoding='utf-8') as f:
        for item in data:
            f.write(','.join(item) + '\n')
    

    8.文件指针

    open 函数返回的文件对象使用文件指针来记录当前在文件中的位置。

    8.1 read 方法

    在读模式下,使用文件对象的 read 方法可以读取文件的内容。它接收一个整数参数表示读取内容的大小,文本模式下表示字符数量,二进制模式下表示字节大小。

    # 读取前面三个字节 '锄禾\n'
    with open('test.txt', 'r', encoding='utf-8') as f:
        content = f.read(3)
        print(content)
    
    with open('test.txt', 'rb') as f:
        content = f.read(3)
        print(content) #输出前面三个字节:b'\xe9\x94\x84',实际上就是一个锄字
    

    '锄'.encode('utf-8') # 三个字节b'\xe9\x94\x84'
    当以读的方式打开文件后文件指针指向文件开头,执行 read 操作之后,根据读取的数据大小指针移动到对应的位置。

    8.2 tell 方法

    文件对象的 tell 方法返回整数,表示文件指针距离文件开头的字节数。

    with open('test.txt', 'r', encoding='utf-8') as f:
        print(f.tell())
        content = f.read(3)
        print(content)
        print(f.tell())
    

    r 模式打开文件后文件指针指向文件开头,执行 read 操作之后,根据读取的数据大小指针移动到对应的位置。

    with open('test.txt', 'a', encoding='utf-8') as f:
        print(f.tell())
    243
    

    a 模式打开文件后文件指针指向文件末尾。

    8.3 seek 方法

    通过文件对象的 seek 方法可以移动文件句柄

    seek 方法接收两个参数:

    • offset 表示偏移指针的字节数
    • whence 表示偏移参考,默认为 0
      0 表示偏移参考文件的开头,offset 必须是 >=0 的整数
      1 表示偏移参考当前位置,offset 可以是负数
      2 表示偏移参考文件的结尾,offset 一般是负数
      注意文本模式下只允许从文件的开头进行偏移,也即只支持 whence=0
    with open('test.txt', 'r', encoding='utf-8') as f:
        print(f.read(3))
        # 跳转到文件开头
        f.seek(0)
        # 再读取第一个字
        print(f.read(1))
    

    锄禾

    with open('test.txt', 'rb') as f:
        # 读取文件最后的10字节
        f.seek(-10,2)
        print(f.read())
    b'\xe5\x8f\x88\xe7\x94\x9f\xef\xbc\x81\n'
    

    相关文章

      网友评论

        本文标题:python自动化测试 第 5 章.文件操作

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