前言
在上篇文章 中,全面讲解了 python 3 中 的面向对象,今天我会继续探险,去掌握 python 3 中的文件操作, let's go 让我们出发吧!
文件
什么是文件?
一谈到文件,就会涉及到一个的重要的概念,持久化 。什么是持久化?
持久化是将程序数据在持久状态和瞬时状态间转换的机制。通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据。 ——来源于百度百科
由此可见,持久化数据就是在程序运行结束后或者断电后再开机,还继续存在的数据。而文件就是最典型的表现形式。那什么是文件呢?
文件就是存储在如硬盘,光盘这样的非易失媒介上的信息序列。像内存,在关机或掉电后,信息就全部丢失了,文件当然不会存储在它上面。
当我们想要读或者写文件时,就得先打开(open) 文件才可以,而当读写完成的时候,也要尽量将其关闭(close),这样才能够释放它占用的系统资源啊。
如何在 python 中打开文件?
使用内置函数 open
就可以打开文件。先来看下 python 中对 open
函数的定义
file object = open(file_name [, access_mode][, buffering])
参数定义如下
-
access_mode
表示文件模式。常见的模式有读模式,写模式,追加模式等。这个参数是可选的,如果不填,默认就是读模式。具体的文件模式列表在下面表格中列出。 -
buffering
缓存标志- 如果不填,默认值为 0
- 值为 1 表示行缓存
- 值 > 1 则代表缓冲区的大小(单位是字节)
- 值 < 0 表示使用默认缓存区的大小
-
file_name
表示要访问的文件路径名称,可以是相对路径,也可以是绝对路径。
具体的文件模式 access_mode
参数表如下
值 | 功能描述 |
---|---|
w | 写模式 |
r | 读模式 |
x | 写模式,创建一个文件,如果文件已存在,则报错 |
a | 追加模式 |
b | 二进制模式(可与其他模式结合使用) |
+ |
读/写模式(可与其他模式结合使用) |
其中 b
或者 +
可与其他模式结合使用需要说明下:
- 如
rb
就表示读取一个二进制文件 - 如
w+
表示对打开的文件可读可写 - 如
wb+
则表示对二进制文件可读可写,如果模式中不加b
则默认表示文本文件
调用 open
函数后返回的是什么对象呢?能够从这个对象中获取什么信息和执行什么操作呢?来看下一节
python 文件对象有哪些属性?
调用 open
函数后返回的是一个文件句柄,这个句柄中包含许多文件相关的属性,具体如下面表格所示
属性 | 功能描述 |
---|---|
file.closed |
文件是否已关闭,是则返回 true |
file.mode |
打开文件时使用的模式 |
file.name |
文件名称 |
来看一个例子
f = open('test.py', 'r+')
# 文件名称.
print ("File name: ", f.name) # test.py
# 文件是否已关闭
print ("File state: ", f.closed) # False
# 文件打开时的模式
print ("Opening mode: ", f.mode) # r+
打开文件后,最常见的操作就是读文件和写文件了,先来看读文件
如何读文件?
在读取文件时, 最常用的方法就是 read()
,readlines()
两个方法,在操作结束后都要调用 close()
方法关闭文件,释放资源。
先来看 read()
方法
read()
打开文件后,
调用
read(size)
方法可以一次读取size
字节的数据如果
read()
方法中没有参数可以一次将文件内容全部读入到内存中
来看一个例子,假设有一个文件名称为 a.txt
内容为
Good morning, everyone!
Good morning, my student!
先来读取前 4 个字母
try:
f = open('a.txt', 'r')
print(f.read(4)) # Good
finally:
if f:
f.close()
上面代码为什么要用 try ... finally
包裹呢?
这是因为文件操作很可能出现 IO 异常的情况,需要使用 try ... finally
包住,即使出现异常也能保证 close()
方法能够正常调用。
其实还有更简洁的写法,就是使用 with
语句,它就是一个语法糖,一下就把 try ... finally
的活都干了。来感受下它的威力
with open('a.txt', 'r') as f:
print(f.read(4)) # Good
readline()
对于文本文件来说,如果比较大,使用 readline()
方法则更为合理,可以一次读取一行内容。
with open('a.txt', 'r') as f:
print(f.readline()) # Good morning teacher!
如果一次想返回多列文本,可以使用 readlines()
方法,它会返回一个列表。
with open('a.txt', 'r') as f:
print(f.readlines()) # ['Good morning teacher!\n', 'Good morning, my student!']
如何写文件?
写文件和读文件操作非常类似,它们的区别就在于:
- 调用
open
方法打开文件时,文件模式需要包含w
,a
或者x
注意, 使用 w
模式打开文件后,执行写入操作,如果文件已经存在,则会将之前的文件内容全部覆盖,之前的数据内容就丢失了啊。如果不想覆盖,还是使用 a
模式打开吧。
调用什么方法可以写文件呢? write()
方法,调用成功后,会返回写入文件的字符长度。
来看一个例子
with open('a.txt', 'w') as f:
f.write('I am line 1\n')
f.write('I am line 2\n')
上面代码中,为什么要加 \n
呢?这是用来分行的,要不然都挤在一行了。
注意,这里如果不使用 with
语法糖,也一定要显式的调用使用 close
方法。这不仅仅是因为释放资源的原因:在调用 write()
方法时,操作系统不会立刻将数据写入到文件中,而是先在内存中缓存,等到空闲时再写入文件,最后使用 close()
方法才会将数据完整的写入到文件中。
当然,显式调用 flush()
方法也可以将数据立即写入文件中。综合比较,还是推荐使用 with
的方式,优雅且完善。
如何操作文件和目录?
除了对文件读和写之外,还会经常用到如获取文件路径,查看文件大小,重命名,删除文件等文件或目录操作。这些操作应该调用哪些方法来完成呢?
强大的 os 模块
刚开始接触 os 模块,就被它强大的 API 列表给震撼了,使用这个模块几乎可以完成所有的日常文件和目录操作。为方便以后查询,我专门将这些常用的操作分门别类,做了一个思维导图。一起来看下。
上图中只给出了最简单的功能介绍,如果想要深入了解具体的方法使用,可参考 python 3.6 os 模块官方地址
学习有时候就是这样,API 太多根本记不住,也没有必要完全记住,只要经常归纳整理,知道要使用的操作在什么地方,叫什么名字,用到的时候去查就可以了。
shutil 模块— High-level file operations
除了 os 模块,还有一个非常有用的模块 shutil
,它的定位是针对多个文件的高级文件操作(High-level file operations)。相比而言, os 模块大多是对单个文件而言的喽。下面通过几个常用的操作来感受下:
- 复制文件夹
shutil.copytree('olddir', 'newdir')
- 注意, 参数
olddir
,newdir
只能是目录,而且newdir
这个目录不存在才可以
- 注意, 参数
- 移动文件或目录
shutil.move('oldpath','newpath')
- 删除目录
shutil.rmtree('dir')
- 看上面的 os 思维导图,也有一个删除目录 API
os.rmdir(dir)
,只能删除空目录 -
shutil.rmtree
功能则更高级,无论是空还是非空目录都可以删除,确实是High-level
啊 _
- 看上面的 os 思维导图,也有一个删除目录 API
对我来说,这三种常用的操作就可以了。当然 shutil
的功能远比这些要丰富的多,有兴趣的同学,可以到 官方文档 去深入了解下。
小结
本篇主要介绍了 python 中文件常用的操作,内容包括打开文件,读文件,写文件,使用 os
和 shutil
模块来操作文件和目录。下篇会介绍 json
和 xml
处理,敬请期待。