目录
1.文件
1.1 文件是什么
1.2 文件路径
1.3 文件操作
1.3.1 打开文件
1.3.2 关闭文件
1.3.3 写文件
1.3.4 读文件
1.3.5 关于中文的处理
1.4 使用上下文管理器
1.文件
1.1 文件是什么
变量是把数据保存到内存中. 如果程序重启/主机重启, 内存中的数据就会丢失.要想能让数据被持久化存储, 就可以把数据存储到硬盘中. 也就是在 文件 中保存.在 Windows "此电脑" 中, 看到的内容都是文件.通过文件的后缀名, 可以看到文件的类型. 常见的文件的类型如下:
- 文本文件 (txt)
- 可执行文件 (exe, dll)
- 图片文件 (jpg, gif)
- 视频文件 (mp4, mov)
- office 文件 (.ppt, docx)
- ......
这里主要研究最简单的文本文件.
1.2 文件路径
一台机器上, 会存在很多文件, 为了让这些文件更方面的被组织, 往往会使用很多的 "文件夹"(也叫做目录)来整理文件.
实际一个文件往往是放在一系列的目录结构之中的.为了方便确定一个文件所在的位置, 使用 文件路径 来进行描述.例如, 上述截图中的 QQ.exe 这个文件, 描述这个文件的位置, 就可以使用路径来表示.D:\QQ\Install\Bin\QQ.exe
- D: 表示 盘符. 不区分大小写.
- 每一个 \ 表示一级目录. 当前 QQ.exe 就是放在 "D 盘下的QQ目录下的 Install目录下的 Bin 目录中" .
- 目录之间的分隔符, 可以使用 \ 也可以使用 / . 一般在编写代码的时候使用 / 更方便.
上述以 盘符 开头的路径, 我们也称为 绝对路径.除了绝对路径之外, 还有一种常见的表示方式是 相对路径. 相对路径需要先指定一个基准目录, 然后以基准目录为参照点, 间接的找到目标文件. 暂时不详细介绍.描述一个文件的位置, 使用 绝对路径 和 相对路径 都是可以的. 对于新手来说, 使用 绝对路径 更简单更好理解, 也不容易出错.
1.3 文件操作
要使用文件, 主要是通过文件来保存数据, 并且在后续把保存的数据读取出来.但是要想读写文件, 需要先 "打开文件", 读写完毕之后还要 "关闭文件".
- 打开文件
- 读文件
- 写文件
- 关闭文件
1.3.1 打开文件
#使用open函数打开一个文件 f = open('D:/CodeFile/test.txt', 'r') print(f) print(type(f))
使用内建函数 open 打开一个文件f = open('D:/CodeFile/test.txt', 'r')
- 第一个参数是一个字符串, 表示要打开的文件路径
- 第二个参数是一个字符串, 表示打开方式. 其中
r 表示按照读方式打开.
w 表示按照写方式打开.a表示追加写方式打开.注:对于f的理解:
- 如果打开文件成功, 返回一个文件对象. 后续的读写文件操作都是围绕这个文件对象展开.
- 如果打开文件失败(比如路径指定的文件不存在), 就会抛出异常.
1.3.2 关闭文件
使用 close 方法关闭已经打开的文件.f.close()使用完毕的文件要记得及时关闭一个程序能同时打开的文件个数, 是存在上限的.flist = [] count = 0 while True: f = open('D:/CodeFile/test.txt', 'r') flist.append(f) count += 1 print(f'打开文件的个数count = {count}')
如上面代码所示, 如果一直循环的打开文件, 而不去关闭的话, 就会出现上述报错.flist = []是把打开的文件保存在列表。注:
8189+3=8192=2^13 (计算机里数据按照2的次幂表示)
当一个程序打开的文件个数超过上限, 就会抛出异常.注意: 上述代码中, 使用一个列表来保存了所有的文件对象. 如果不进行保存, 那么 Python 内置的垃圾回收机制, 会在文件对象销毁的时候自动关闭文件.但是由于垃圾回收操作不一定及时, 所以我们写代码仍然要考虑手动关闭, 尽量避免依赖自动关闭.flist = [] count = 0 while True: f = open('D:/CodeFile/test.txt', 'r') flist.append(f) f.close() count += 1 print(f'打开文件的个数count = {count}')
其实在系统中可以通过一些设置项来配置能打开的最大数目的。
注:
- 打开文件,其实是在申请一定的系统资源
- 不再使用文件的时候,资源就应该及时释放,否则造成文件资源泄露,进一步的导致其他部分的代码也无法顺利打开文件了。正是因为一个系统的资源是有限的,因此以个程序能打开的文件个数也是有上限的。
- Python有一个重要的机制——垃圾回收机制(GC),自动的把不使用的变量进行释放。但自动释放不一定及时
1.3.3 写文件
文件打开之后, 就可以写文件了.
- 写文件, 要使用写方式打开, open 第二个参数设为 'w' 使用 write 方法写入文件.
#使用write来实现写文件的操作 f = open('D:/CodeFile/test.txt', 'w') f.write('2023兔年大吉,万事胜意!') f.close()
用记事本打开文件, 即可看到文件修改后的内容.
- 如果是使用 'r' 方式打开文件, 则写入时会抛出异常.
f = open('D:/CodeFile/test.txt', 'r') f.write('2023兔年大吉,万事胜意!') f.close()
- 使用 'w' 一旦打开文件成功, 就会清空文件原有的数据.
- 使用 'a' 实现 "追加写", 此时原有内容不变, 写入的内容会存在于之前文件内容的末尾.
#写方式有两种:'w'(直接写方式) 和 'a'(追加写方式) f = open('D:/CodeFile/test.txt', 'a') f.write('hello,python!') f.close()
- 针对已经关闭的文件对象进行写操作, 也会抛出异常
#写方式有两种:'w'(直接写方式) 和 'a'(追加写方式) f = open('D:/CodeFile/test.txt', 'a') f.write('\nhello,python!\n') f.close() f.write('每一天都弥足珍贵!\n \t——By 新晓故知')
1.3.4 读文件
- 读文件内容需要使用 'r' 的方式打开文件
- 使用 read 方法完成读操作. 参数表示 "读取几个字符"
f = open('D:/CodeFile/test.txt', 'r') result = f.read(2) print(result) f.close()
- 如果文件是多行文本, 可以使用 for 循环一次读取一行.
先构造一个多行文件.f = open('D:/CodeFile/test.txt', 'r') for line in f: print(f'line = {line}') f.close()
注意: 由于文件里每一行末尾都自带换行符, print 打印一行的时候又会默认加上一个换行符, 因此打印结果看起来之间存在空行.(之所以多了个空行,是因为本来就读到的文件内容末尾就带有‘\n’,此处使用print来打印,又会自动加一个换行符,可以给print再多设定个参数,修改print自动添加换行的行为)使用 print(f'line = {line}', end='') 手动把 print 自带的换行符去掉.f = open('D:/CodeFile/test.txt', 'r') for line in f: print(f'line = {line}', end='') f.close()
- 使用 readlines 直接把文件整个内容读取出来, 返回一个列表. 每个元素即为一行.
#还可以使用readlines方法直接把整个文件内容读出按照行组织到一个列表。 f = open('D:/CodeFile/test.txt', 'r') lines = f.readlines() print(lines) f.close()
此处的 \n 即为换行符.
1.3.5 关于中文的处理
当文件内容存在中文的时候, 读取文件内容不一定就顺利.同样上述代码, 可能执行时可能会出现异常也有可能出现乱码.计算机表示中文的时候, 会采取一定的编码方式, 我们称为 "字符集"
- 所谓 "编码方式" , 本质上就是使用数字表示汉字.
- 我们知道, 计算机只能表示二进制数据. 要想表示英文字母, 或者汉字, 或者其他文字符号, 就都要通过编码.
- 最简单的字符编码就是 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: 字符编码问题, 是编程中一类比较常见, 又比较棘手的问题. 需要对于字符编码有一定的理解, 才能从容应对.
同学们可以参考腾讯官方账号发表的帖子, 详细介绍了里面的细节. 程序员必备:彻底弄懂常见的7种中文字符编码 - 知乎1.4 使用上下文管理器
打开文件之后, 是容易忘记关闭的. Python 提供了 上下文管理器 , 来帮助程序猿自动关闭文件.
- 使用 with 语句打开文件.
- 当 with 内部的代码块执行完毕后, 就会自动调用关闭方法
def func(): with open('d:/test.txt', 'r') as f: lines = f.readlines() print(lines)
当with对应的代码块执行结束,就会自动的执行f.close().