我们知道当⽂件不存在的时候,open()⽅法的写模式与追加模式都会新建⽂件,但是对⽂件进⾏判
我们之前学过,要⽤with语句来处理⽂件读写,但with语句也不是万能的,所以还得关注⼀些异常情况。 例如,当使⽤open()⽅法的时候,如果⽂件不存在,程序会抛出FileNotFoundError异常,⽽如果权限不⾜的话,就会抛出PersmissionError异常。
一.懒人的try语句
我们之前学过,要⽤with语句来处理⽂件读写,但with语句也不是万能的,所以还得关注⼀些异常情况。
例如,当使⽤open()⽅法的时候,如果⽂件不存在,程序会抛出FileNotFoundError异常,⽽如果权限不足的话,就会抛出PersmissionError异常。
with open("python.log", "r") as f:
...: f.read()
-----------------------
...(略)
FileNotFoundError: [Errno 2] No such file or directory: 'python.log'39
为了避免这些异常导致程序中断,我们可以⽤try...except...语句来捕捉异常,然后在except⼦句进⾏异常的处理。
不过,这个⽅法不值得推荐。原因有⼆,⼀是这种⽅法很被动,程序的健康受制于不可预测的异常;⼆是当⽂件不存在的时候,我们可能需要去创建⽂件,这些逻辑如果写在except⼦句⾥,可读性太差了。
二.传统的os模块
顾名思义,Python内置的os模块是⽤来与OS(操作系统)进⾏交互的模块,它可以实现很多在命令⾏下做的操作,例如,获取操作系统信息、获取/修改环境变量、进⾏⽬录操作(创建、删除、遍历)和各种⽂件操作等等。
下⾯,我们要学习的是跟⽂件判断密切相关的⼏个⽅法。
1、os.path.exists()⽤于判断⽂件及⽂件夹是否存在(注意:因为两者都能判断,为了有效区分⽂件和⽂件夹,最好保证⽂件是带后缀的。):
import os
# ⽂件存在 VS 不存在
os.path.exists("test.txt") >>>True
os.path.exists("cat.txt") >>>False
# ⽂件夹存在 VS 不存在
os.path.exists("cat/images") >>>True
os.path.exists("cat/image") >>>False
2、os.path.isfile()、os.path.isdir() 判断给定路径是⽂件还是⽂件夹:
os.path.isfile("cat/images") >>>False
os.path.isdir("cat/images") >>>True
os.path.isfile("test.txt") >>>True
3、os.access()检测⽂件路径的访问权限,语法:os.access(path, mode);其中path指的是⽂件或者文件夹,mode指的是要检测的模式:
os.access("cat/images", os.F_OK) >>>True # path存在
os.access("cat/images", os.R_OK) >>>True # path可读
os.access("cat/images", os.W_OK) >>>True # path可写
os.access("cat/images", os.X_OK) >>>True # path可执⾏
4、os模块中其它常⽤⽅法:
os.mkdir()创建⽬录、os.rmdir()删除⽬录、os.rename()重命名、os.remove()删除⽂件、os.path.join()连接⽬录与⽂件名、os.path.split()分割⽬录与⽂件名......
三.时尚的pathlib模块
pathlib模块是python3.4才加⼊的模块,官⽅介绍它是⾯向对象的⽂件系统路径(Object-oriented filesystem paths),这是⼀个很强⼤的模块,⽂末附录了官⽅⽂档地址。
这⾥主要介绍⼏个基本的⽤法:
import pathlib
file_obj = pathlib.Path("test.txt")
file_obj.name >>>'test.txt' # ⽂件名
file_obj.exists() >>> True # 是否存在
file_obj.is_dir() >>>False # 是否⽂件夹
file_obj.is_file() >>>True # 是否⽂件
四.几种方法优劣对比
围绕⽂件操作的知识很多,限于篇幅,本⽂主要对判断⽂件作了介绍,今后也许还会对其它具体话题进⾏学习。
现在知道了⼏种判断⽂件是否存在的⽅法,根据自己 的理解,对它们做⼀下评判。
⾸先,try语句的缺点是没有主动做判断,不⽅便根据⽂件是否存在⽽做针对性的处理,它把必要的逻辑交给异常捕获,多少显得“不负责任”;try语句也有优点,⼀是不需要引⼊模块,不需要区分各种使⽤⽅法,⼆是将其它可能存在的异常都打包,避免多样系统或使⽤场景的遗漏。
os模块是传统的⽼模块了,在使⽤上和维护上都会⽐较顺畅;它的主要缺点在于有的⽅法⽐较繁琐,由于使⽤字符串来表示⽂件路径,这会导致路径拼接上的麻烦,另外,不同操作系统在路径分隔符上的差异(Windows使⽤\分隔符,Linux和Mac使⽤/分隔符),也可能导致难以发现的错误。
相对来说,pathlib功能最强⼤,但普及度⽐较低,有⼀定的学习⻔槛;它主要的优点是⾯向对象,同时,因为对不同操作系统的特性做了封装,能有效避免字符串表示⽂件路径的难题。它的不⾜之处是没有像os.access()可以检测访问权限的⽅法,虽然这个⽅法基本不会使⽤到。
下⾯⽐较了三种拼接⽂件路径的⽅法,⽅法⼀未对分隔符做处理,不能保证在每个操作系统都能找到;方法二需要反复使⽤os.path.join;⽅法三只⽤“/"就能拼接路径,⽽且肯定⽀持多操作系统。
# 错误拼接:未处理分隔符
data_folder = "source_data/text_files/"
file_to_open = data_folder + "test.txt"
# os模块拼接
import os
data_folder = os.path.join("source_data", "text_files")
file_to_open = os.path.join(data_folder, "test.txt")
# pathlib模块拼接
from pathlib import Path
data_folder = Path("source_data/text_files/")
file_to_open = data_folder / "test.txt"
总结⼀下,如果⽂件路径简单,仅仅要⽤到exists()、is_dir()、is_file() 这⼏个⽅法的话,os.path模块和pathlib.Path模块不分伯仲,都很好⽤,但是如果考虑到繁复的路径拼接的话,pathlib.Path就会胜出一筹。
扩展阅读:
给Python学习者的⽂件读写指南
https://mp.weixin.qq.com/s/Md07VoaULda7qnMO4ob7Ww
菜⻦教程:os模块
http://www.runoob.com/python/os-file-methods.html
官⽅⽂档:pathlib模块
https://docs.python.org/3/library/pathlib.html