【Python】6.基础语法(6)文件
文章目录
- 1. 文件是什么
- 2. 文件路径
- 3. 文件操作
- 3.1 打开文件
- 3.2 关闭文件
- 3.3 写文件
- 3.4 读文件
- 4. 关于中文的处理
- 5. 使用上下文管理器
1. 文件是什么
变量是把数据保存到内存中。如果程序重启/主机重启, 内存中的数据就会丢失。
要想能让数据被持久化存储, 就可以把数据存储到硬盘中。也就是在文件中保存。
通过文件的后缀名, 可以看到文件的类型。
常见的文件的类型如下:
文本文件 (
txt
)可执行文件 (
exe, dll
)图片文件 (
jpg, gif
)视频文件 (
mp4, mov
)office 文件 (
ppt, docx
)…
2. 文件路径
一个机器上, 会存在很多文件, 为了让这些文件更方面的被组织, 往往会使用很多的 “文件夹”(也叫做目录) 来整理文件。
实际一个文件往往是放在一系列的目录结构之中的。
为了方便确定一个文件所在的位置, 使用 文件路径 来进行描述。
例如, 上述截图中的 QQ.exe
这个文件, 描述这个文件的位置, 就可以使用路径C:\Program Files\Tencent\QQNT\QQ.exe
来表示。
C:
表示 盘符,不区分大小写。每一个
\
表示一级目录。当前QQ.exe
就是放在C
盘下的Program Files
目录下的Tencent
目录下的QQNT
目录中。目录之间的分隔符, 可以使用
\
也可以使用/
。一般在编写代码的时候使用/
更方便,因为存在转义字符。
上述以 盘符 开头的路径, 我们也称为 绝对路径
。
除了绝对路径之外, 还有一种常见的表示方式是 相对路径
。相对路径需要先指定一个基准目录, 然后以基准目录为参照点, 间接的找到目标文件。
描述一个文件的位置, 使用 绝对路径 和 相对路径 都是可以的。对于新手来说, 使用绝对路径更简单更好理解, 也不容易出错。
3. 文件操作
要使用文件, 主要是通过文件来保存数据, 并且在后续把保存的数据读取出来。
但是要想读写文件, 需要先 “打开文件”, 读写完毕之后还要 “关闭文件”。
3.1 打开文件
使用内建函数 open
打开一个文件.
f = open('d:/test.txt', 'r')
print(f)
print(type(f))
打印:
<_io.TextIOWrapper name='d:/test.txt' mode='r' encoding='cp936'>
<class '_io.TextIOWrapper'>
第一个参数是一个字符串, 表示要打开的文件路径
第二个参数是一个字符串, 表示打开方式。
r
表示read
,按照读方式打开
。
w
表示write
,按照写方式打开
。
a
表示append
,追加写方式打开
,把内容写到原有文件内容的末尾。
如果打开文件成功, 返回一个文件对象。后续的读写文件操作都是围绕这个文件对象展开。
如果打开文件失败(比如路径指定的文件不存在), 就会抛出异常。
open
的返回值是一个文件对象。文件的内容是在硬盘上的,此处的文件对象,是内存上的一个变量。
后续读写文件操作,都是拿着这个文件对象来进行操作的。
3.2 关闭文件
使用 close
方法关闭已经打开的文件。
f = open('d:/test.txt', 'r')
print(f)
print(type(f))
f.close()
使用完毕的文件要记得及时关闭!
因为打开文件,实际上是在申请一定的系统资源,不再使用文件的时候,资源就应该及时释放。
正因为一个系统的资源是有限的,所以一个程序能同时打开的文件个数, 是存在上限的。
flist = []
count = 0
while True:
f = open('d:/test.txt', 'r')
flist.append(f)
count += 1
print(f'count = {count}')
打印:
如上面代码所示, 如果一直循环的打开文件, 而不去关闭的话, 就会出现上述报错。当一个程序打开的文件个数超过上限, 就会抛出异常。
注意: 上述代码中, 使用一个列表来保存了所有的文件对象:flist.append(f)
如果不进行保存, 那么 Python
内置的垃圾回收机制, 会在文件对象销毁的时候自动关闭文件。但是由于垃圾回收操作不一定及时, 所以我们写代码仍然要考虑手动关闭, 尽量避免依赖自动关闭。
8189+3=8192=2^13
为什么要加
3
呢?因为每个程序在启动的时候,都会默认打开
3
个文件:
- 标准输入:键盘
input
- 标准输出:显示器
- 标准错误:显示器
3.3 写文件
文件打开之后, 就可以写文件了。
写文件, 要使用写方式打开, open
第二个参数设为 ‘w
’。使用 write
方法写入文件。
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
打印:
用记事本打开文件, 即可看到文件修改后的内容。
如果是使用 ‘r
’ 方式打开文件, 则写入时会抛出异常。
f = open('d:/test.txt', 'r')
f.write('hello')
f.close()
打印:
使用 ‘w
’ 一旦打开文件成功, 就会清空文件原有的数据。
使用 ‘a
’ 实现 “追加写”, 此时原有内容不变, 写入的内容会存在于之前文件内容的末尾。
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
f = open('d:/test.txt', 'a')
f.write('world')
f.close()
打印:
针对已经关闭的文件对象进行写操作, 也会抛出异常。
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
f.write('world')
打印:
3.4 读文件
读文件内容需要使用 ‘r
’ 的方式打开文件,使用 read
方法完成读操作。参数表示 “读取几个字符”
f = open('d:/test.txt', 'r')
result = f.read(2)
print(result)
f.close()
打印:
he
注意:
这里读取的是两个字符而不是两个字节,所以即使是汉字也是读取两个汉字。
如果文件是多行文本, 可以使用 for
循环一次读取一行。
先构造一个多行文件。
代码:
f = open('d:/test.txt', 'r')
for line in f:
print(f'line = {line}')
f.close()
打印:
line = hello
line = world
line = !
注意:
由于文件里每一行末尾都自带换行符, print
打印一行的时候又会默认加上一个换行符, 因此打印结果看起来之间存在空行。
我们可以使用 print(f'line = {line}', end='')
手动把 print
自带的换行符去掉。
使用 readlines
直接把文件整个内容读取出来, 返回一个列表。每个元素即为一行。
f = open('d:/test.txt', 'r')
lines = f.readlines()
print(lines)
f.close()
打印:
['hello\n', 'world\n', '!']
此处的 \n
即为换行符。
f = open('d:/test.txt', 'r')
lines = f.readlines()
print(lines)
f.close()
打印:
['helloworld\n', '!']
此处的 \n
即为换行符。
f = open('d:/test.txt', 'r')
lines = f.readlines()
print(lines)
f.close()
打印:
这个是因为记事本里面使用的不是gbk
编码,而是UTF-8
编码。
我们需要添加一段代码:encoding='utf8'
(这个叫做关键字参数)
代码:
f = open('d:/test.txt', 'r', encoding='utf8')
lines = f.readlines()
print(lines)
f.close()
打印:
此处的 \n
即为换行符。
4. 关于中文的处理
当文件内容存在中文的时候, 读取文件内容不一定就顺利。
同样上述代码, 有的同学执行时可能会出现异常,也有的可能出现乱码。
计算机表示中文的时候, 会采取一定的编码方式, 我们称为 “字符集”。
所谓 “编码方式” , 本质上就是使用数字表示汉字。
我们知道, 计算机只能表示二进制数据。要想表示英文字母, 或者汉字, 或者其他文字符号, 就都要通过编码。
最简单的字符编码就是
ASCII
。使用一个简单的整数就可以表示英文字母和阿拉伯数字。但是要想表示汉字, 就需要一个更大的码表。一般常用的汉字编码方式, 主要是
GBK
和UTF-8
必须要保证文件本身的编码方式, 和 Python
代码中读取文件使用的编码方式匹配, 才能避免出现上述问题。
Python3
中默认打开文件的字符集跟随系统, 而Windows
简体中文版的字符集采用了GBK
, 所以如果文件本身是GBK
的编码, 直接就能正确处理。如果文件本身是其他编码(比如
UTF-8
), 那么直接打开就可能出现上述问题。
使用记事本打开文本文件, 在 “菜单栏” -> “文件” -> “另存为” 窗口中, 可以看到当前文件的编码方式。
如果此处的编码为 ANSI
, 则表示 GBK
编码。
如果此处为 UTF-8
, 则表示 UTF-8
编码。
此时修改打开文件的代码, 给 open
方法加上 encoding
参数, 显式的指定为和文本相同的字符集, 问题即可解决。
f = open('d:/test.txt', 'r', encoding='utf8')
PS: 字符编码问题, 是编程中一类比较常见, 又比较棘手的问题。需要对于字符编码有一定的理解, 才能从容应对。
可以参考腾讯官方账号发表的帖子, 详细介绍了里面的细节。 https://zhuanlan.zhihu.com/p/46216008
5. 使用上下文管理器
打开文件之后, 是容易忘记关闭的。例如:代码里面有条件判定,函数返回,抛出异常…
Python
提供了 上下文管理器 , 来帮助程序猿自动关闭文件。
使用
with
语句打开文件。当
with
内部的代码块执行完毕后, 就会自动调用关闭方法。
with open('d:/test.txt', 'r', encoding='utf8') as f:
lines = f.readlines()
print(lines)
打印:
['床前明月光\n', '疑是地上霜']
类似的操作在C++
里面有智能指针
,java
里面有try with Resources
,Golang
里面有defer
。