1. 程式人生 > >Python遞迴遍歷目錄下所有檔案查詢指定檔案

Python遞迴遍歷目錄下所有檔案查詢指定檔案

之前看到網上有人說『os.path.isdir()判斷必須寫絕對路徑』,當時心想Python不是有迭代上下文嗎,為什麼不行?遂作本文驗證之

程式碼部分

考慮用一個path變數指代當前遍歷元素的絕對路徑(正確做法)

def search(root, target):
    items = os.listdir(root)
    for item in items:
        path = os.path.join(root, item)
        if os.path.isdir(path):
            print('[-]', path)
            search(path, target)
        elif
path.split('/')[-1] == target: print('[+]', path) else: print('[!]', path)

正常遍歷的結果

這裡寫圖片描述

如果這樣寫,把路徑全部換成item(迭代元素)

def search(root, target):
    items = os.listdir(root)
    for item in items:
        if os.path.isdir(item):
            print('[-]', item)
            search(os.path.join(root, item), target)
        elif
item == target: print('[+]', os.path.join(root,item)) else: print('[!]', os.path.join(root, item))

這裡寫圖片描述

可以看出,這是行不通的:如果使用item迭代元素進行指代當前路徑,最多隻會再往下遞迴兩層(子資料夾、子資料夾的檔案),可見所未的上下文管理機制在這裡是完全不起作用的

反思和總結

1)如果在正確遍歷寫法基礎上,僅改變每次遞迴時的傳遞元素迭代機制會做出怎樣的反應?

在上面的例子中,只需要把search(os.path.join(root, item), target)

改成search(item, target)即可:

這裡寫圖片描述

這一點很容易看出,因為在首次呼叫search(..)函式時就是傳入了一個絕對路徑,如果傳入相對路徑因為沒有上下文環境,是不能正確定位檔案位置的

2)os.path.abspath(path)方法可以替代os.path.join(root, current)嗎?

實踐出真知:

這裡寫圖片描述

(大霧)原來os.path.abspath(..)表示的是:相對當前工作目錄的相對路徑!(而不是相對系統根目錄的相對路徑!)

所以,os.path.abspath(..)os.path.join(..)是兩個完全不同的東西,是不能替換的

3)Python的檔案到底是什麼呢?

還是那份正確的程式碼,將每一條輸出改成用type(..)函式包裹的形式

這裡寫圖片描述

在看下面另一個例子

這裡寫圖片描述

本著Python中『一切皆物件』的信念,我們輸入的路徑(包括它的迭代版本、用來接受它的變數)是一個字串str物件,而用來描述檔案的檔案控制代碼(指標)則是一個_io.TextIOWrapper型別的物件

通常我們在資料夾、檔案水平查詢、篩選,用的是str型別的路徑描述,而要對具體某個檔案(不是資料夾)進行讀或寫的操作,就要用到_io.TextIOWrapper型別的檔案控制代碼,它們分的比較細;不像Java中完全被封裝成了一個File(String path)物件,它弱化了檔案路徑的作為單獨個體的作用——但是Python則把路徑單獨拎出來,我們很多的檔案操作(廣義上比如查詢指定檔案,不單指檔案IO),都是建立在檔案路徑的基礎上的

4)思考:除了開頭給出的方法,有沒有別的遍歷檔案辦法?

答案是:有的(yes)

這裡寫圖片描述

os.chdir(path)函式可以改變當前工作目錄到指定path

但是我們不推薦使用該方法,因為它修改了全域性變數,這一點在函式呼叫前後使用os.getcwd()函式進行驗證

先把工作目錄切換到根目錄下,接著執行自定義的change()函式

這裡寫圖片描述

如你所見,這時候全域性的當前工作目錄已經發生了改變