• 23.Python文件I/O(一)【详解open()函数&上下文管理器with...as】


    每篇前言:


    在这里插入图片描述

    Python文件I/O(一)

    1.1 基本方法

    1.1.1 打开和关闭文件

    用open()函数打开一个文件,创建一个file对象,调用相关的方法即可对文件进行读写。
    完整的语法格式为:

    open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)
    
    • 1

    参数说明:

    • file: 必需,文件路径(可以是绝对路径,也可以是相对路径)。
    • mode: 可选,文件打开模式。
    • buffering: 寄存区的缓冲大小。设为0,不会有寄存。设为负值,寄存区的缓冲大小则为系统默认。默认寄存区的缓冲大小为0。
    • encoding: 一般使用utf8。
    • errors: 报错级别。
    • newline: 区分换行符。
    • closefd: 传入的file参数类型。

    mode具体参数列表:
    在这里插入图片描述
    总结:

    • 加个b的作用:以二进制的格式打开文件(比如操作音频文件,图片文件,视频文件…),进行上述操作。

    • 在这里插入图片描述

    1.1.2 file对象的属性

    以下是和file对象相关的所有属性的列表:
    在这里插入图片描述

    • file 对象的 close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。

    • 当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。用 close()方法关闭文件是一个很好的习惯。

    • 注意:打开一个文件操作完之后,一定要关闭。

    1.1.3 知识点补给站

    • windows系统中:
      相对路径:不带盘符的。
      绝对路径:带盘符的。
    • 光标位置:
      1.如果读完了就读不了了,因为光标的位置在最后
      2.通过seek方法重新调整光标的位置
      3.写完了后,光标位置在最后
      例子看看:

    f = open(r’ceshi.py’,‘r+’)
    f.read()
    ‘wumou love zhangmou’
    f.read() #现在就读不了了,因为光标在上一次读完之后移动到了最后。
    ‘’
    f.seek(0) #把光标位置调整到最前面,那么光标后面就有内容了
    0
    f.read() #现在就可以读到内容了
    ‘wumou love zhangmou’
    f.tell() #可以查看光标的位置
    24
    f.seek(0)
    0
    f.tell()
    0

    上述方法下一小节会细讲~

    1.1.4 文件基本读写与定位

    • write()方法可将任何字符串写入一个打开的文件。
      语法:fileObject.write(string)

    • read()方法从一个打开的文件中读取指定长度的字符串(括号里加要读的指定的字符串长度,不写则全读)。
      语法:fileObject.read([count])

    • tell()描述文件当前位置
      语法:fileObject.tell()

    • seek()改变当前文件的位置
      语法:seek(offset [,from])
      参数:
        offset变量表示要移动的字节数
        from变量指定参考位置。0,表示开头。1,表示当前的位置。2,表示末尾(默认为0)
      例如:
        seek(x,0) : 从起始位置即文件首行首字符开始移动 x 个字符
        seek(x,1) : 表示从当前位置往后移动x个字符
        seek(-x,2):表示从文件的结尾往前移动x个字符

    实战讲解:

    # -*- coding: utf-8 -*-
    """
    __author__ = 小小明-代码实体
    """
    # 以二进制格式打开一个文件用于读写.如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    fo = open("foo.txt", "wb+")
    # 向文件写入2句话
    fo.write(b"blog.xiaoxiaoming.xyz!\nVery good site!\n")
    seq = [b"blog.xiaoxiaoming.xyz!\n", b"Very good site!"]
    fo.writelines(seq)
    
    # 查找当前位置
    print("当前文件位置 : ", fo.tell())
    # 写完数据,文件指针在文件末尾,现在重定向到文件开头
    fo.seek(0)
    # 读取10个字符
    print("当前文件位置 : ", fo.tell())
    str = fo.read(10)
    print("读取的字符串是 : ", str)
    print("当前文件位置 : ", fo.tell())
    # 关闭打开的文件
    fo.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    foo.txt文件内容:
    在这里插入图片描述

    1.1.5 close()

    处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,如果尝试再调用该文件,则会抛出异常。

    >>> f.close()
    >>> f.read()
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: I/O operation on closed file
    
    • 1
    • 2
    • 3
    • 4
    • 5

    当处理一个文件对象时, 使用 with 关键字是非常好的方式。在结束后, 它会帮你正确的关闭文件。 而且写起来也比 try - finally 语句块要简短:

    >>> with open('/tmp/foo.txt', 'r') as f:
    ...     read_data = f.read()
    >>> f.closed
    True
    
    • 1
    • 2
    • 3
    • 4

    1.1.6 file(文件)的方法

    file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数:
    在这里插入图片描述

    • 调用read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容。
    • 调用next()或readline()可以每次读取一行内容,f.next() 逐行读取数据,和f.readline() 相似,唯一不同的是,readline() 读取到最后如果没有数据会返回空,而next() 没读取到数据则会报错。
    • 调用readlines()一次读取所有内容并按行返回list。因此,要根据需要决定怎么调用。
    • 如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便。

    可能有小伙伴不是很理解flush()的作用,其实我们可以浅显的将它的作用理解为保存。下面来个代码讲解一下:

    举个例子:
    文件内容是:   wumou
    
    >> f1 = open('ceshi.py','a')
    >> f1.write('shuai')
    5
    >> f2 = open('ceshi.py','r')
    >> f2.read()        				 #会发现现在读是读不到刚刚以追加方式写进入的内容shuai
    'wumou'
    >> f1.flush()       				 #我们立即刷新缓冲,那么下面就可以读到了。此处作用相当于在进行文件操作之后进行保存
    >> f2.seek(0)
    0
    >> f2.read()
    'wumoushuai'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    实战讲解:

    • 创建tmp.txt文件内容为:
      在这里插入图片描述
    • 上代码:
    # -*- coding: utf-8 -*-
    """
    __author__ = 小小明-代码实体
    """
    fo = open("tmp.txt", "r", encoding="utf-8")
    # 立即刷新缓冲区 ——>  可以理解为保存  
    fo.flush()
    print("文件名为: ", fo.name)
    print("文件描述符为: ", fo.fileno())
    print("文件连接到一个终端设备:", fo.isatty())
    # next返回文件下一行
    for index in range(5):
        line = fo.readline()
        print("第 %d 行 - %s" % (index + 1, line), end="")
    print()
    
    fo.seek(0)
    for line in fo.readlines():
        print(line, end="")
    
    # 关闭文件
    fo.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    总结:

    • 持久存储:保存内存中数据都是易丢失的,只有保存在硬盘中才能持久的存储,保存在硬盘中的基本方法就是把数据写入文件中。
    • 打开和关闭:在python中文件的打开与关闭变得十分简单快捷,文件在关闭的时候就会自动保存。

    1.1.7 上下文管理 with…as

    每次都写try … finally来关闭文件实在太繁琐,所以,Python引入了with语句来自动帮我们调用close()方法,代码如下:

    with open("tmp.txt", encoding="utf-8") as f:
        for line in f:
            print(line, end="")
    
    • 1
    • 2
    • 3
    • 作用:
      让python自动执行关闭过程,即调用close()方法。
      管理多个文件自动关闭。

    首先来看,单个文件操作时:

    # -*- coding: utf-8 -*-
    """
    __author__ = 孤寒者
    """
    with open(file_path, mode='r') as f:
        # 对f进行一系列操作
        # 也可以执行别的操作
    
    # 跳出with语句的时候自动执行f.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    然后来看,多个文件操作时:

    # -*- coding: utf-8 -*-
    """
    __author__ = 孤寒者
    """
    with open(file_path, mode='r') as f1,\
             open(file_path, mode='r') as f2,\
             .
             .
             .
             open(file_path, mode='r') as fn:
        # 对f进行一系列操作
        # 也可以执行别的操作
    
    file.closed  查看文件是否关闭了
    
    # 跳出with语句块的时候自动执行f.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    最后来看看:
    两个底层方法:__enter____exit__

    # -*- coding: utf-8 -*-
    """
    __author__ = 孤寒者
    """
    class Person:
        def __enter__(self):                        # 进入的时候自动调用
            print('this is enter')
            return '吴某好帅'
    
    
        def __exit__(self,exc_type,exc_val,exc_tb):    #退出的时候自动调用
            print("this is exit")
    
    #with可以打开类,进行多个方法的管理
    a = Person()
    with a as f:           #with可以管理多个软件,打开多个软件。
        print(111)         #我们打开这个类,就会自动调用__enter__方法,然后进行打印111的操作
        print(f)           #f就是__enter__的返回值
    #结束之后就会自动调用__exit__方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

  • 相关阅读:
    iOS应用加固方案解析:ipa加固安全技术全面评测
    【单元测试】--高级主题
    产品经理基础--07用户端产品设计
    Reactive响应式WebClient负载调用微服务接口封装,自行编写类OpenFeign的Reactive实现
    计算机毕业论文微信小程序毕业设计开题报告ssm在线学习平台小程序+后台管理系统|前后分离VUE[包运行成功]
    【差旅游记】公乌素遇到的那些司机师傅
    前端面试指南之React篇(二)
    思科华为设备端口聚合配置命令对比
    通信基础之天线知识梳理---2022/12/05
    YOLOv5算法改进(16)— 增加小目标检测层 | 四头检测机制(包括代码+添加步骤+网络结构图)
  • 原文地址:https://blog.csdn.net/qq_44907926/article/details/125488240