上週,貓貓寫了一篇給Python學習者的文件讀寫指南,跟你們一塊兒詳盡地學習了文件讀寫的基礎內容,以及with語句與上下文管理器的進階知識。html
這份指南雖然寫得很用心,可是由於只關注了文件讀寫的核心內容,因此也有美中不足不處,有些在實戰中所需的知識點沒有談到,例如,爲了可以進行文件讀寫,首先得找到文件、文件得可讀寫才行。
python
咱們知道當文件不存在的時候,open()方法的寫模式與追加模式都會新建文件,可是對文件進行判斷的場景還有不少,好比,在爬蟲下載圖片的時候,可能須要判斷文件是否存在,以避免重複下載;又好比,建立新文件的時候,可能須要判斷文件是否存在,存在就先作個備份……因此,學習判斷文件是否存在,仍是頗有必要的。ruby
學習是按部就班的過程,若能創建知識點間的聯繫,進行系統性的學習,那將更有助於效果。閱讀這篇文章,你將讀到以下內容:微信
一、判斷文件的方法(try語句、os模塊、pathlib模塊)
二、以上幾種方法的優劣對比app
懶人的try語句
咱們以前學過,要用with語句來處理文件讀寫,但with語句也不是萬能的,因此還得關注一些異常狀況。學習
例如,當使用open()方法的時候,若是文件不存在,程序會拋出FileNotFoundError異常,而若是權限不足的話,就會拋出PersmissionError異常。ui
with open("python.log", "r") as f:
...: f.read()
-----------------------
...(略)
FileNotFoundError: [Errno 2] No such file or directory: 'python.log'
爲了不這些異常致使程序中斷,咱們能夠用try…except…語句來捕捉異常,而後在except子句進行異常的處理。lua
不過,在貓貓看來,這個方法不值得推薦。緣由有二,一是這種方法很被動,程序的健康受制於不可預測的異常;二是當文件不存在的時候,咱們可能須要去建立文件,這些邏輯若是寫在except子句裏,可讀性太差了。url
傳統的os模塊
顧名思義,Python內置的os模塊是用來與OS(操做系統)進行交互的模塊,它能夠實現不少在命令行下作的操做,例如,獲取操做系統信息、獲取/修改環境變量、進行目錄操做(建立、刪除、遍歷)和各類文件操做等等。下面,咱們要學習的是跟文件判斷密切相關的幾個方法。spa
一、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
二、os.path.isfile()、os.path.isdir() 判斷給定的路徑是文件仍是文件夾:
os.path.isfile("cat/images") >>>False
os.path.isdir("cat/images") >>>True
os.path.isfile("test.txt") >>>True
三、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可執行
四、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就會勝出一籌。
喵喵,今天的分享就到這啦,小夥伴們以爲有用的話,麻煩幫忙點贊、轉發給其餘童靴哦~~~
另外,爲了回饋各位好學的胖友們,貓貓精選了20本電子書,如今去後臺回覆【愛學習】,便可免費得到哦喵~~~
擴展閱讀:
給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
一隻僞喵星來客
一個有趣又有用的學習分享平臺
專一python技術、數據科學和深度學習
兼具極客思惟與人文情懷
歡迎你關注
微信號:python_cat
本文分享自微信公衆號 - Python貓(python_cat)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。