【Python】文件

文章目录

  • [1. 文件是什么](#1. 文件是什么)
  • [2. 文件路径](#2. 文件路径)
  • [3. 文件操作](#3. 文件操作)
    • [3.1 打开文件](#3.1 打开文件)
    • [3.2 关闭文件](#3.2 关闭文件)
    • [3.3 写文件](#3.3 写文件)
    • [3.4 读文件](#3.4 读文件)
  • [4. 关于中文的处理](#4. 关于中文的处理)
  • [5. 使用上下文管理器](#5. 使用上下文管理器)

1. 文件是什么

变量是把数据保存到内存中。如果程序重启 / 主机重启,内存中的数据就会丢失。

要想能让数据被持久化存储,就可以把数据存储到硬盘中。也就是在 文件 中保存。

在 Mac 系统的 "访达" 中,看到的内容都是文件。如下图所示:

通过文件的后缀名,可以看到文件的类型。常见的文件的类型如下:

  • 文本文件 (txt)
  • 可执行文件 (exe, dll)
  • 图片文件 (jpg, gif)
  • 视频文件 (mp4, mov)
  • office 文件 (.ppt, docx)
  • ...

2. 文件路径

一个机器上,会存在很多文件,为了让这些文件更方面的被组织,往往会使用很多的 "文件夹"(也叫做 目录)来整理文件。

实际一个文件往往是放在一系列的目录结构之中的。为了方便确定一个文件所在的位置,使用 文件路径 来进行描述。

例如,上述截图中的 QQ.exe 这个文件,描述这个文件的位置,就可以使用路径 D:\program\qq\Bin\QQ.exe 来表示。

  • D: 表示盘符。不区分大小写。
  • 每一个 \ 表示一级目录。当前 QQ.exe 就是放在 "D 盘下的 program 目录下的 qq 目录下的 Bin 目录中"。
  • 目录之间的分隔符,可以使用 \ 也可以使用 /。一般在编写代码的时候使用 / 更方便。

上述以盘符开头的路径,我们也称为绝对路径

除了绝对路径之外,还有一种常见的表示方式是相对路径。相对路径需要先指定一个基准目录,然后以基准目录为参照点,间接的找到目标文件。

描述一个文件的位置,使用 绝对路径相对路径 都是可以的。对于新手来说,使用 绝对路径 更简单更好理解,也不容易出错。

3. 文件操作

要使用文件,主要是通过文件来保存数据,并且在后续把保存的数据读取出来。

但是要想读写文件,需要先 "打开文件",读写完毕之后还要 "关闭文件"。

3.1 打开文件

使用内建函数 open 打开一个文件。

python 复制代码
f = open('/Users/edison/Work_Python/myPython/test.txt', 'r')

其中:

  • 第一个参数是一个字符串,表示要打开的文件路径
  • 第二个参数是一个字符串,表示打开方式。其中 r 表示按照读方式打开,w 表示按照写方式打开,a 表示追加写方式打开。
  • 如果打开文件成功,返回一个文件对象。后续的读写文件操作都是围绕这个文件对象展开。
  • 如果打开文件失败(比如路径指定的文件不存在),就会抛出异常。

3.2 关闭文件

使用 close 方法关闭已经打开的文件。

python 复制代码
f.close()

使用完毕的文件要记得及时关闭!

另外,一个程序能同时打开的文件个数,是存在上限的。

python 复制代码
flist = []
count = 0
while True:
    f = open('/Users/edison/Work_Python/myPython/test.txt', 'r')
    flist.append(f)
    count += 1
    print(f'count = {count}')

运行结果如下:如果一直循环的打开文件,而不去关闭的话,就会出现下面的报错。

当一个程序打开的文件个数超过上限,就会抛出异常。需要注意的是:

  • 上述代码中,使用一个列表来保存了所有的文件对象。如果不进行保存,那么 Python 内置的垃圾回收机制,会在文件对象销毁的时候自动关闭文件。
  • 但是由于垃圾回收操作不一定及时,所以我们写代码仍然要考虑手动关闭,尽量避免依赖自动关闭。

3.3 写文件

文件打开之后,就可以写文件了。

  • 写文件,要使用写方式打开,open 第二个参数设为 'w'
  • 使用 write 方法写入文件。
python 复制代码
f = open('./test.txt', 'w')
f.write('hello world')
f.close()

结果如下:

  • 如果是使用 'r' 方式打开文件,则写入时会抛出异常。
python 复制代码
f = open('./test.txt', 'r')
f.write('hello')
f.close()

运行结果如下:

  • 使用 'w' 一旦打开文件成功,就会清空文件原有的数据。
  • 使用 'a' 实现 "追加写",此时原有内容不变,写入的内容会存在于之前文件内容的末尾。
python 复制代码
f = open('./test.txt', 'w')
f.write('good')
f.close()

f = open('./test.txt', 'a')
f.write('edison')
f.close()

运行结果如下:

  • 针对已经关闭的文件对象进行写操作,也会抛出异常。
python 复制代码
f = open('./test.txt', 'w')
f.write('hello')
f.close()
f.write('world')

运行结果如下:

3.4 读文件

我们现在 test.txt 文件中写入:你好。

  • 读文件内容需要使用 'r' 的方式打开文件
  • 使用 read 方法完成读操作。参数表示"读取几个字符"
python 复制代码
f = open('./test.txt', 'r')
result = f.read(2)
print(result)
f.close()

运行结果如下:

  • 如果文件是多行文本,可以使用 for 循环一次读取一行。(记得先构造一个多行文件)
python 复制代码
f = open('./test.txt', 'r')
for line in f:
    print(f'line = {line}')
f.close()

运行结果如下:

注意:

  • 由于文件里每一行末尾都自带换行符,print 打印一行的时候又会默认加上一个换行符,因此打印结果看起来之间存在空行。
  • 使用 print(f'line = {line}', end='') 手动把 print 自带的换行符去掉。

如下所示:

  • 使用 readlines 直接把文件整个内容读取出来,返回一个列表。每个元素即为一行。
python 复制代码
f = open('./test.txt', 'r')
lines = f.readlines()
print(lines)
f.close()

运行结果如下:

注意:此处的 \n 即为换行符。

4. 关于中文的处理

当文件内容存在中文的时候,读取文件内容不一定就顺利。

同样上述代码,有的人执行时可能会出现下面这样的异常:

复制代码
UnicodeDecodeError: 'gbk' codec can't decode byte 0x89 in position 14: illegal multibyte sequence

亦或者,可能出现乱码。

计算机表示中文的时候,会采取一定的编码方式,我们称为 "字符集"

  • 所谓"编码方式",本质上就是使用数字表示汉字。
  • 我们知道,计算机只能表示二进制数据。要想表示英文字母,或者汉字,或者其他文字符号,就都要通过编码。
  • 最简单的字符编码就是 ASCII 编码。使用一个简单的整数就可以表示英文字母和阿拉伯数字。
  • 但是要想表示汉字,就需要一个更大的码表。
  • 一般常用的汉字编码方式,主要是 GBKUTF-8

必须要保证文件本身的编码方式,和 Python 代码中读取文件使用的编码方式匹配,才能避免出现上述问题。

  • Python3 中默认打开文件的字符集跟随系统,而 Windows 简体中文版的字符集采用了 GBK,所以如果文件本身是 GBK 的编码,直接就能正确处理。
  • 如果文件本身是其他编码(比如 UTF-8),那么直接打开就可能出现上述问题

5. 使用上下文管理器

打开文件之后,是容易忘记关闭的。Python 提供了 上下文管理器,来帮助程序猿自动关闭文件。

  • 使用 with 语句打开文件。
  • 当 with 内部的代码块执行完毕后,就会自动调用关闭方法。

代码如下:

python 复制代码
with open('./test.txt', 'r', encoding='utf8') as f:
    lines = f.readlines()
    print(lines)

运行结果如下:

相关推荐
cccccc语言我来了1 分钟前
Linux(9)操作系统
android·java·linux
jason成都4 分钟前
IoT 设备监控系统实战:基于 EMQX 的 MQTT 连接监控与数据格式指纹识别
开发语言·python
yige4531 分钟前
【MySQL】MySQL内置函数--日期函数字符串函数数学函数其他相关函数
android·mysql·adb
愤豆32 分钟前
05-Java语言核心-语法特性--模块化系统详解
java·开发语言·python
AI-Ming44 分钟前
程序员转行学习 AI 大模型: 踩坑记录:服务器内存不够,程序被killed
服务器·人工智能·python·gpt·深度学习·学习·agi
洞见前行1 小时前
AI 当逆向工程师:Claude Code 自主分析 APK 和 so 文件,解决 Unity 插件化启动崩溃
android·人工智能
2401_873544921 小时前
使用Python处理计算机图形学(PIL/Pillow)
jvm·数据库·python
路由侠内网穿透1 小时前
本地部署开源工作空间工具 AFFiNE 并实现外部访问
运维·服务器·数据库·物联网·开源
努力进修1 小时前
旧安卓手机别扔!用KSWEB搭个人博客,搭配外网访问超香
android·智能手机·cpolar
zzzsde1 小时前
【Linux】Ext文件系统(1)
linux·运维·服务器