2012-06-12 64 views
9

根目錄循環,目錄,os.walk(startdir)中的文件通過這些步驟工作? C:啓動目錄的我瞭解os.walk嗎?

for root in os.walk(startdir) 
    for dir in root 
     for files in dir 
  1. 獲得root \ DIR1 \ DIR2 \ STARTDIR

  2. 讓用C文件夾:\ DIR1 \ DIR2 \ STARTDIR和返回的文件夾 「dirlist」

  3. 名單
  4. 獲取第一個dirlist項目中的文件並返回文件列表「filelist」作爲文件列表的第一項。

  5. 移動到dirlist中的第二項並返回文件夾「filelist2」中的文件列表作爲文件列表的第二項。等

  6. 移動到下一個根foldertree和2等

正確的開始?或者它只是首先得到所有的根,然後所有的第二個和所有的文件第三?

+1

爲什麼我這應該是一個減1?我做錯什麼了嗎? – Baf

回答

13

os.walk返回一個發電機,創建值(的current_path,在目錄中的current_path,在文件的current_path)的元組。

每次調用生成器時,它都會遞歸地跟隨每個目錄,直到沒有其他子目錄可用於初始目錄,該目錄將被調用。

因此,

os.walk('C:\dir1\dir2\startdir').next()[0] # returns 'C:\dir1\dir2\startdir' 
os.walk('C:\dir1\dir2\startdir').next()[1] # returns all the dirs in 'C:\dir1\dir2\startdir' 
os.walk('C:\dir1\dir2\startdir').next()[2] # returns all the files in 'C:\dir1\dir2\startdir' 

所以

import os.path 
.... 
for path, directories, files in os.walk('C:\dir1\dir2\startdir'): 
    if file in files: 
      print 'found %s' % os.path.join(path, file) 

或本

def search_file(directory = None, file = None): 
    assert os.path.isdir(directory) 
    for cur_path, directories, files in os.walk(directory): 
     if file in files: 
      return os.path.join(directory, cur_path, file) 
    return None 

,或者如果你想尋找的文件,你可以這樣做:

import os 
def search_file(directory = None, file = None): 
    assert os.path.isdir(directory) 
    current_path, directories, files = os.walk(directory).next() 
    if file in files: 
     return os.path.join(directory, file) 
    elif directories == '': 
     return None 
    else: 
     for new_directory in directories: 
      result = search_file(directory = os.path.join(directory, new_directory), file = file) 
      if result: 
       return result 
     return None 
+0

我喜歡os.path解決方案,因此os.path將始終與os.walk在該迭代過程中所在的目錄相對應? – Baf

+0

thx也samir! – Baf

+0

btw所有上述答案都值得一個答案標籤,但我只能標記其中一個帖子作爲答案!不好,還是有辦法標記多個帖子作爲答案? – Baf

2

os.walk的工作方式與上面有所不同。基本上,它返回(路徑,目錄,文件)的元組。看到這一點,請嘗試以下操作:

import pprint 
import os 
pp=pprint.PrettyPrinter(indent=4) 
for dir_tuple in os.walk("/root"): 
    pp.pprint(dir_tuple) 

...你會看到,每次循環會立即在該目錄中打印目錄名,列表中的任何目錄的名稱,而另一個列表該目錄中的所有文件。然後os.walk將進入子目錄列表中的每個目錄,並執行相同的操作,直到遍歷了原始根目錄的所有子目錄。這可能有助於瞭解一些關於遞歸的知識,以瞭解它是如何工作的。

+0

Thx很多alex! – Baf

+0

ima給予遞歸閱讀。所以在for循環中,我做了元組項,如果我使用if語句檢查文件,它只會檢查語句 – Baf

+0

也這個pprint是非常整潔的感謝! – Baf

3

下面是os.walk()如何使用幾個os函數以及一些解釋的簡短示例。

首先要注意os.walk()回報3個項目,根目錄,目錄的立即當前根下方的列表(dirs),並在這些目錄中的文件列表。 documentation會給你更多的信息。

dirs將包含根目錄下方的目錄列表,並且文件將包含在這些目錄中找到的所有文件的列表。在下一次迭代中,前一個dirs列表中的每個目錄將依次擔任root的角色,並且搜索將從那裏繼續,只有在搜索完當前級別後纔會繼續搜索。

代碼示例:這將搜索,計數並打印指定搜索目錄(您的根目錄)下面的.jpg.gif文件的名稱。它還利用os.path.splitext()函數將文件的基部與其擴展名和os.path.join()函數分開,以爲您提供全名,包括找到的圖像文件的路徑。

import os 

searchdir = r'C:\your_root_dir' # your search starts in this directory (your root) 

count = 0 
for root, dirs, files in os.walk(searchdir): 
    for name in files: 
     (base, ext) = os.path.splitext(name) # split base and extension 
     if ext in ('.jpg', '.gif'):   # check the extension 
      count += 1 
      full_name = os.path.join(root, name) # create full path 
      print(full_name) 

print('\ntotal number of .jpg and .gif files found: %d' % count) 
+0

thx levon很徹底!你stackoverflow的人搖滾! – Baf

+3

爲了防止任何人在搜索os.walk和「寬度優先」後絆倒了這一點 - 上述信息不正確。 os.walk(至少在python 2.6和2.7中)進行了深度優先遍歷,而不是廣度優先遍歷。 項目獲取的確切順序取決於topdown參數 - 如果topdown爲True(默認值),那麼它會進行預先深度優先遍歷(https://en.wikipedia.org/wiki/File: Sorted_binary_tree_preorder.svg),而如果它是False,它會執行後序深度優先遍歷(https://en.wikipedia.org/wiki/File:Sorted_binary_tree_postorder.svg)。 –

5

簡而言之,os.walk()將生成路徑,文件夾,給定路徑中存在的文件的元組,並將繼續遍歷子文件夾。

import os.path 
path=input(" enter the path\n") 
for path,subdir,files in os.walk(path): 
    for name in subdir: 
     print os.path.join(path,name) # will print path of directories 
    for name in files:  
     print os.path.join(path,name) # will print path of files 

這將產生的所有子目錄,文件和文件路徑的子目錄