【例 1】默认打开 "a.txt" 文件。
纯文本复制
  1. #当前程序文件同目录下没有 a.txt 文件
  2. file = open("a.txt")
  3. print(file)
#当前程序文件同目录下没有 a.txt 文件
file = open("a.txt")
print(file)
当以默认模式打开文件时,默认使用 r 权限,由于该权限要求打开的文件必须存在,因此运行此代码会报如下错误:

FileNotFoundError Traceback (most recent call last)
<ipython-input-4-dad991fb07c9> in <module>
----> 1 file=open("a.txt")
2 print(file)

FileNotFoundError: [Errno 2] No such file or directory: 'a.txt'

现在,在程序文件同目录下,手动创建一个 a.txt 文件,并再次运行该程序,其运行结果为:

<_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'>

可以看到,当前输出结果中,输出了 file 文件对象的相关信息,包括打开文件的名称、打开模式、打开文件时所使用的编码格式。
使用 open() 打开文件时,默认采用 GBK 编码。但当要打开的文件不是 GBK 编码格式时,可以在使用 open() 函数时,手动指定打开文件的编码格式,例如:

file = open("a.txt",encoding="utf-8")

注意,手动修改 encoding 参数的值,仅限于文本文件的形式打开,也就是说,以二进制格式打开时,不能对 encoding 参数的值做任何修改,否则程序会抛出 ValueError 异常,如下所示:

ValueError: binary mode doesn't take an encoding argument

open()是否需要缓冲区

通常情况下、建议大家在使用 open() 函数时打开缓冲区,即不需要修改 buffing 参数的值。

果 buffering 参数值为大于 1 的整数,该整数用于指定缓冲区的大小(单位是字节);如果 buffering 参数的值为负数,则代表使用默认的缓冲区大小。

为什么呢?原因很简单,目前为止计算机内存的 I/O 速度仍远远高于计算机外设(例如键盘、鼠标、硬盘等)的 I/O 速度,如果不使用缓冲区,则程序在执行 I/O 操作时,内存和外设就必须进行同步读写操作,也就是说,内存必须等待外设输入(输出)一个字节之后,才能再次输出(输入)一个字节。这意味着,内存中的程序大部分时间都处于等待状态。
而如果使用缓冲区,则程序在执行输出操作时,会先将所有数据都输出到缓冲区中,然后继续执行其它操作,缓冲区中的数据会有外设自行读取处理;同样,当程序执行输入操作时,会先等外设将数据读入缓冲区中,无需同外设做同步读写操作。

open()函数返回的文件对象常用的属性

成功打开文件之后,可以调用文件对象本身拥有的属性获取当前文件的部分信息,其常见的属性为:
  • file.name:返回文件的名称;
  • file.mode:返回打开文件时,采用的文件打开模式;
  • file.encoding:返回打开文件时使用的编码格式;
  • file.closed:判断文件是否己经关闭。
  • 举个例子:
    纯文本复制
    1. # 以默认方式打开文件
    2. f = open('my_file.txt')
    3.  
    4. # 输出文件是否已经关闭
    5. print(f.closed)
    6.  
    7. # 输出访问模式
    8. print(f.mode)
    9.  
    10. #输出编码格式
    11. print(f.encoding)
    12.  
    13. # 输出文件名
    14. print(f.name)
    # 以默认方式打开文件
    f = open('my_file.txt')
    # 输出文件是否已经关闭
    print(f.closed)
    # 输出访问模式
    print(f.mode)
    #输出编码格式
    print(f.encoding)
    # 输出文件名
    print(f.name)
    程序执行结果为:

    False
    cp936
    my_file.txt

    注意,使用 open() 函数打开的文件对象,必须手动进行关闭python 垃圾回收机制无法自动回收打开文件所占用的资源。

  • 利用文件对象关闭文件——file.close()
  • with ... as ...上下文管理器打开文件
  • 使用 with as 操作打开的文件对象(本身就是上下文管理器),无论期间是否抛出异常,都能保证 with as 语句执行完毕后自动关闭已经打开的文件。
    首先学习如何使用 with as 语句。with as 语句的基本语法格式为: with 表达式 [as target]:
    此格式中,用 [ ] 括起来的部分可以使用,也可以省略。其中,target 参数用于指定一个变量,该语句会将 expression 指定的结果保存到该变量中。with as 语句中的代码块如果不想执行任何语句,可以直接使用 pass 语句代替。
    举个例子,假设有一个 a.txt 文件,其存储内容如下: C语言中文网
    http://c.biancheng.net

    在和 a.txt 同级目录下,创建一个 .py 文件,并编写如下代码:

    1. with open('a.txt', 'a') as f:
    2. f.write("\nPython教程")
    with open('a.txt', 'a') as f:
        f.write("\nPython教程")
    运行结果为: C语言中文网
    http://c.biancheng.net
    Python教程

    with open("a.txt") as fr,open("b.txt",mode="w") as fw:
    fw.writelines(fr.readlines( )) with open("a.txt") as fr:
    with open("b.txt",mode="w") as fw:
    fw.writelines(fr.readlines( ))
    可以看到,通过使用 with as 语句,即便最终没有关闭文件,修改文件内容的操作也能成功。 (了解)简单的理解,同时包含 __enter__() 和 __exit__() 方法的对象就可以使用with as上下文管理器。文件对象内部实现了__enter__() 和 __exit__() 方法 __enter__(self):进入上下文管理器自动调用的方法,该方法会在 with as 代码块执行之前执行。如果 with 语句有 as子句,那么该方法的返回值会被赋值给 as 子句后的变量;该方法可以返回多个值,因此在 as 子句后面也可以指定多个变量(多个变量必须由“()”括起来组成元组)。 __exit__(self, exc_type, exc_value, exc_traceback):退出上下文管理器自动调用的方法。该方法会在 with as 代码块执行之后执行。如果 with as 代码块成功执行结束,程序自动调用该方法,调用该方法的三个参数都为 None:如果 with as 代码块因为异常而中止,程序也自动调用该方法,使用 sys.exc_info 得到的异常信息将作为调用该方法的参数。