2015-10-14 172 views
10

Python 3.5's os.scandir(path)函數返回對文件信息非常有用的輕量級DirEntry對象。但是,它只適用於交給它的直接路徑。有沒有辦法將它包裝在遞歸函數中,以便它訪問給定路徑下的所有子目錄?如何使用os.scandir()在目錄樹上遞歸地返回DirEntry對象?

+1

看一看[os.walk()](https://docs.python.org/3.5/library /os.html#os.walk)。它可能比你想要的更加沉重,但它應該比創建自己的解決方案更簡單。 – skrrgwasme

回答

14

可以掃描遞歸使用os.walk(),或者如果您需要DirEntry對象或更多的控制,寫一個遞歸函數像下面scantree()

try: 
    from os import scandir 
except ImportError: 
    from scandir import scandir # use scandir PyPI module on Python < 3.5 

def scantree(path): 
    """Recursively yield DirEntry objects for given directory.""" 
    for entry in scandir(path): 
     if entry.is_dir(follow_symlinks=False): 
      yield from scantree(entry.path) # see below for Python 2.x 
     else: 
      yield entry 

if __name__ == '__main__': 
    import sys 
    for entry in scantree(sys.argv[1] if len(sys.argv) > 1 else '.'): 
     print(entry.path) 

注:

  • 這裏有幾個例子在PEP 471os.scandir() docs
  • 您還可以在for循環中添加各種邏輯以跳過以'.'開頭的目錄或文件等等。
  • 您通常想在is_dir()上調用follow_symlinks=false這樣的遞歸函數來避免符號鏈接循環。
  • 關於Python 2.x中,替換與yield from行:

    for entry in scantree(entry.path): 
        yield entry 
    
+0

由於'os.scandir'只存在於Python 3.5中,因此可能不需要Python 2後備代碼。 :-) __Edit:__啊,如果'os.scandir'不存在,你寫它來導入PyPI模塊,我猜PyPI模塊可用於2.7? – ShadowRanger

+0

@ShadowRanger好吧,這是真的,但是這種方式可以使用我的[scandir]模塊(https://pypi.python.org/pypi/scandir)爲Python <3.5(包括Python 2.x)工作。 :-) –

+0

@ShadowRanger我已經添加了代碼註釋來澄清。 –