和其他编程语言一样,Python 也具有操作文件(I/O)的能力,比如打开文件、读取和追加数据、插入和删除数据、关闭文件、删除文件等。合理应用python提供的文件操作基本函数,可大大提高自动化实现的效率与框架代码的稳定性。
一、文件路径
绝对路径:总是从根文件夹开始,Window 系统中以盘符(C:、D:)作为根文件夹,而 OS X 或者 Linux 系统中以 / 作为根文件夹。
相对路径:指的是文件相对于当前工作目录所在的位置。例如,当前工作目录为 "C:\Windows\System32",若文件 demo.txt 就位于这个 System32 文件夹下,则 demo.txt 的相对路径表示为 ".\demo.txt"(其中 .\ 就表示当前所在目录),如果要表示上级目录,我们可用..\表示,在上述例子可定位到Windows文件夹
Python os.path 模块提供了一些函数,可以实现绝对路径和相对路径之间的转换
- 调用 os.path.abspath(path) 将返回 path 参数的绝对路径的字符串,这是将相对路径转换为绝对路径的简便方法。
import os
file_path = r'./t0704_4.py'
file_path_abs = os.path.abspath(file_path)
print(file_path_abs)
结果:
/Users/jie/PythonProjects/jctesting_study/D0704_3/t0704_4.py
- 调用 os.path.isabs(path),如果参数是一个绝对路径,就返回 True,如果参数是一个相对路径,就返回 False。
- 调用 os.path.split(path) 将返回一个元祖,它包含path参数的目录名称和基本名称。
import os
file_path = r'/Users/jie/PythonProjects/jctesting_study/D0704_3/t0704_4.py'
path_split = os.path.split(file_path)
print(path_split)
结果:
('/Users/fujinjie/PythonProjects/jctesting_study/D0704_3', 't0704_4.py')
调用 os.path.dirname(path) 将返回一个字符串,它包含 path 参数中最后一个斜杠之前的所有内容;调用 os.path.basename(path) 将返回一个字符串,它包含 path 参数中最后一个斜杠之后的所有内容。
import os
file_path = r'/Users/jie/PythonProjects/jctesting_study/D0704_3/t0704_4.py'
path_dir = os.path.dirname(file_path)
print(path_dir)
path_base = os.path.basename(file_path)
print(path_base)
结果:
/Users/jie/PythonProjects/jctesting_study/D0704_3
t0704_4.py
调用os.path.exists(path)判断这个path是否存在,返回一个布尔值,True代表存在,False代表不存在
# 判断log_path是否存在,如果不存在就创建这个log_path
if not os.path.exists(log_path):
os.makedirs(log_path)
二、文件操作
写入、读取:是文件最常用的操作,作用于文件的内容,属于应用级操作;对于文件的应用级操作,通常需要按照固定的步骤进行操作
- 打开文件:使用 open() 函数,该函数会返回一个文件对象;
- 对已打开文件做读/写操作:读取文件内容可使用 read()、readline() 以及 readlines() 函数;向文件中写入内容,可以使用 write() 函数。
- 关闭文件:完成对文件的读/写操作之后,最后需要关闭文件,可以使用 close() 函数。
(一)、打开文件
Python中通过内置的 open( )函数来打开文件,open()函数常用调用方法如下
file = open(file_name, mode, encoding)
- file:表示要创建的文件对象。
- file_name:要创建或打开文件的文件名称,该名称要用引号(单引号或双引号都可以)括起来。需要注意的是,如果要打开的文件和当前执行的代码文件位于同一目录,则直接写文件名即可;否则,此参数需要指定打开文件所在的完整路径。
- mode:可选参数,用于指定文件的打开模式。可选的打开模式如表 1 所示。如果不写,则默认以只读(r)模式打开文件。
- encoding:手动设定打开文件时所使用的编码格式,不同平台的 ecoding 参数值也不同,以 Windows 为例,其默认为 cp936(实际上就是 GBK 编码)。
file = open('/Users/jie/Downloads/测试文件1.txt','r',encoding='utf-8')
open( ) 中传入要打开的"文件地址+文件名",以及标示符'r'(r,表示只读)
open函数支持的文件打开模式
文件打开模式,直接决定了后续可以对文件做哪些操作。例如,使用 r 模式打开的文件,后续编写的代码只能读取文件,而无法修改文件内容。
成功打开文件之后,可以调用文件对象本身拥有的属性获取当前文件的部分信息,其常见的属性为:
- file.name:返回文件的名称;
- file.mode:返回打开文件时,采用的文件打开模式;
- file.encoding:返回打开文件时使用的编码格式;
- file.closed:判断文件是否己经关闭。
(二)、读取文件read()、readline()、readlines()函数
通过 read( ) 函数对打开的文件进行内容全部的读取,文件内容以str对象放入内存中
file.read()
print(file.read()) # 欢迎来到精创学习!
print(type(file.read())) # <class 'str'>
读取完文件后,我们需要通过 close( ) 函数把文件进行关闭,文件使用完后需要被关闭,因为文件对象会占用系统资源,并且系统同一时间能打开的文件数量是有限制的
file.close() # 调用close()函数来关闭打开的文件来释放被占用的系统资源
注意:想使用 read() 函数成功读取文件内容,除了严格遵守 read() 的语法外,其还要求 open() 函数必须以可读默认(包括 r、r+、rb、rb+)打开文件。举个例子,将上面程序中 open()的打开模式改为 w,程序会抛出io.UnsupportedOperation
异常,提示文件没有读取权限
通过上述代码,我们来结合try...except...finally来完成文件的打开-读取-关闭
def read_file(file_name='/Users/jie/Downloads/测试文件1.txt'):
f = None
try:
f = open(file_name,'r',encoding='utf-8')
r = f.read()
print(r)
except:
print("文件读取异常!")
finally:
if f:
f.close()
print('关闭打开的文件')
s = read_file()
这里定义了一个了函数 read_file(file_name) 来实现文件读取功能,函数中,给变量f默认值为None, 目的在于程序一执行就会自动创建变量f,供下面try: 和 finally: 语句调用;
问题:上述代码为什么要在一开始就定义变量: f 呢?
Python中 read( ) 函数会一次性读取文件的全部内容到内存中,试设想,如果这个文件非常庞大,那么内存就会溢出,因此在调用read( ) 函数读取文件时,要注意读取对象数据量,如果想按行读取可调用 readline( ),这样每次读取一行;调用 read(size) 方法,每次读取 size 个字节的内容,还有 readlines( ) 也是一次读取所有内容,但是按行读取,返回一个list,所以读取文件时要根据实际灵活运用上面三个函数。
readline( )
def read_file(file_name='C:\\Users\\37210\\Desktop\\测试文件1.txt'):
f = None
try:
f = open(file_name,'r',encoding='utf-8')
while f:
r = f.readline()
if r:
print(r)
else:
break
except Exception as e:
print("文件读取异常!")
print(e)
finally:
if f:
f.close()
print('关闭打开的文件')
s = read_file()
这是文本第1行。
这是文本第2行。
这是文本第3行。
关闭打开的文件
readline()方法每次读取一行;返回的是一个字符串对象,保持当前行的内存;即通过循环按行读取。
readlines( )
def read_file(file_name='C:\\Users\\37210\\Desktop\\测试文件1.txt'):
f = None
try:
f = open(file_name,'r',encoding='utf-8')
r = f.readlines()
print(r) # ['这是文本第1行。\n', '这是文本第2行。\n', '这是文本第3行。\n']
for i in r: # 通过循环遍历这个list
print(i)
except Exception as e:
print("文件读取异常!")
print(e)
finally:
if f:
f.close()
print('关闭打开的文件')
s = read_file()
['这是文本第1行。\n', '这是文本第2行。\n', '这是文本第3行。\n']
这是文本第1行。
这是文本第2行。
这是文本第3行。
关闭打开的文件
readlines( ) 方法一次性读取全部内容到内存,每一行字符串作为一个元素,返回一个list,可通过for循环来遍历这个list,获取每行内容
上述返回结果
['这是文本第1行。\n', '这是文本第2行。\n', '这是文本第3行。\n']
列表中每个元素都包含一个'\n',即回车符,导致输出结果含有空行,这里可使用 replace( ) 函数来处理
for i in r:
i = i.replace('\n','') # 通过replace把'\n'替换成'',达到去除'\n'的目的
print(i)
这是文本第1行。
这是文本第2行。
这是文本第3行。
关闭打开的文件
任务:分别通过read( ) 、readline( ) 、readlines( ) 对文本完成打开-读取-关闭
任务:通过replace( ) 函数,把读取到的字符串中'。'代替为'!'
(三)、关闭文件
close()函数是专门用来关闭已经打开的文件的,语法如下:
file.close()
期中,file表示已打开的文件对象,对于已经通过open()函数打开的文件,操作完成后一定要调用close()函数进行关闭,进行系统资源释放,否则程序容易出现问题。
(四)、通过 with open ...as...语句来打开一个文件
上面我们已经了解通过open()函数打开一个文件后需要通过close()来关闭这个打开的文件,目的是释放资源,防止资源泄露,在python中提供了with...as...语句来操作上下文管理器,以及时释放资源,使用 with as 操作已经打开的文件对象,无论期间是否抛出异常,都能保证 with as 语句执行完毕后自动关闭已经打开的文件。
基本表达式:
with 表达式 as 别名(变量):
代码块
上述读取一个文件的操作是 :open-read-close,通过 with open 可简化步骤:with open-read
通过 with 关键字,当文件读取完毕,程序会自动关闭文件,无需调用 close( ) 函数
def read_file(file_name='C:\\Users\\37210\\Desktop\\测试文件1.txt'):
try:
with open(file_name,'r',encoding='utf-8') as f:
r = f.readlines()
print(r)
for i in r:
i = i.replace('\n','')
print(i)
except Exception as e:
print("文件读取异常!")
print(e)
if f.closed: # 通过调用 f.closed 来判断打开的文件是否已关闭,已关闭返回True,否则返回False
print('文件已关闭')
s = read_file()
['这是文本第1行。\n', '这是文本第2行。\n', '这是文本第3行。\n']
这是文本第1行。
这是文本第2行。
这是文本第3行。
文件已关闭
任务:通过 whit open...as... 来改造上述代码的 read( ) 、readline( )
(五)、写入文件
写入文件时把open函数中 'r' 改成 'w',通过 f.write(要写入的内容) 来对文件进行写入操作,同样需要close( )函数来关闭打开的文件
基本语法格式:
file.write(string)
def read_file(file_name='C:\\Users\\37210\\Desktop\\测试文件1.txt'):
f = None
try:
f = open(file_name,'w',encoding='utf-8')
w = f.write('写入第一句话。')
except Exception as e:
print("写入文件异常!")
print(e)
finally:
if f:
f.close()
print('关闭打开的文件')
s = read_file()
此时打开'C:\\Users\\37210\\Desktop\\测试文件1.txt'文件,会发现文件中存在的是“写入第一句话。”字符串
通过 with open ... as...来简化
def read_file(file_name='C:\\Users\\37210\\Desktop\\测试文件1.txt'):
try:
with open(file_name,'w',encoding='utf-8') as f:
f.write('写入第二句话。')
except BasException as e:
print("写入文件异常!")
print(e)
s = read_file()
同样通过 with open ... as ..来写入文件,可以省略close( )方法,上述通过参数 'w' 来写入会直接覆盖原文件,把 'w' 改成 'a' 就可以实现追加的方式写入
def read_file(file_name='C:\\Users\\37210\\Desktop\\测试文件1.txt'):
try:
with open(file_name,'a',encoding='utf-8') as f: # 以追加的方式写入
f.write('写入第二句话。')
except Exception as e:
print("写入文件异常!")
print(e)
s = read_file()
写入第一句话。写入第二句话。
打开'C:\\Users\\37210\\Desktop\\测试文件1.txt'文件,文件中:“写入第一句话。写入第二句话。”
如果,在写入操作时,file_name不存在,则程序会自动创建这个名称的文件,并写入数据。
任务:在桌面创建一个新的空文本文件,分别通过 open...write...close 的方式写入一句话
任务:对上一任务通过 with open...as... 来改造简化
任务:结合上一任务,以追加的形式写入