2011-12-13 52 views
0

我正在嘗試創建一個通過目錄的walker。這是我部分工作的輸入和輸出。我正在使用一個測試目錄,但是我希望在導致某些問題的任何目錄上完成此操作。在python中分配os.walk中的實例

[IN]: print testdir #name of the directory 
[OUT]: ['j','k','l'] #directories under testdir 

[IN]: print testdir.j 
[OUT]: ['m','n'] # Files under testdir.j 

這是迄今爲止代碼:

class directory_lister: 
    """Lists directories under root""" 
    def __init__(self,path): 
     self.path = path 
     self.ex = [] 
     for item in os.listdir(path): 
      self.ex.append(item) 
    def __repr__(self): 
     return repr(self.ex) 

這將返回目錄和文件,但我必須手動指定目錄的名稱。

testdir = directory_lister(path/to/testdir) 
j = directory_lister(path/to/j) 
etc 

是否有辦法來自動實例這樣的:

for root,dirs,files in os.walk(/path/to/testdir/): 
    for x in dirs: 
     x = directory_lister(root) #I want j = directory_lister(path/to/j), k = directory_lister(path/to/k) and l = directory_lister(path/to/l) here. 

纔會有:

class directory_lister: 
    def __init__(self,path): 
     self.path = path 
     self.j = directory_lister(path + os.sep + j) # how to automate this attribute of the class when assigned to an instance?? 

上面的代碼是錯誤的,因爲對象x只有成爲一個實例,但j,k,l必須手動定義。我是否需要使用其他課程或字典getattr但我總是遇到同樣的問題。如果需要任何額外的信息,請問,我希望我明確說明。

更新2

有沒有辦法通過下面阿努拉格添加其他複雜功能的DirLister?所以當它到達一個文件時會說testdir/j/p,它會打印出文件p的第一行。

[IN] print testdir.j.p 
[OUT] First Line of p 

我已經做了類打印出來的文件的第一行:

class File: 
    def __init__(self, path): 
     """Read the first line in desired path""" 
     self.path = path 
     f = open(path, 'r') 
     self.first_line = f.readline() 
     f.close() 

    def __repr__(self): 
     """Display the first line""" 
     return self.first_line 

只需要知道如何將它下面的類。謝謝。

+0

到底是什麼`directory_lister`的期望的接口和功能? – 2011-12-13 17:49:13

+0

`os.walk`已經列出了所有的目錄和文件,那麼`directory_lister`的含義是什麼? – ekhumoro 2011-12-13 18:04:02

+0

@KarlKnechtel,功能是方便地列出根目錄下的目錄。所以你只需指定根目錄,其餘的就很容易查看。 – Neeran 2011-12-14 09:22:11

回答

1

我想,你希望子目錄要像一個屬性的訪問,則可以實現兩個方面

  • 我們將向您文件的列表,並創建變量動態
  • 掛接到屬性的訪問和根據需要

我更喜歡第二種方法,因爲它是懶惰的,更好,更容易實現

正確返回大腕3210
import os 

class DirLister(object): 
    def __init__(self, root): 
     self.root = root 
     self._list = None 

    def __getattr__(self, name): 
     try: 
      var = super(DirLister).__getattr__(self, name) 
      return var 
     except AttributeError: 
      return DirLister(os.path.join(self.root, name)) 

    def __str__(self): 
     self._load() 
     return str(self._list) 

    def _load(self): 
     """ 
     load once when needed 
     """ 
     if self._list is not None: 
      return 
     self._list = os.listdir(self.root) # list root someway 

root = DirLister("/") 
print root.etc.apache2 

輸出:

['mods-enabled', 'sites-80', 'mods-available', 'ports.conf', 'envvars', 'httpd.conf', 'sites-available', 'conf.d', 'magic', 'apache2.conf', 'sites-enabled'] 

您可以改善這種有更好的錯誤檢查等

代碼解釋:這是基本目錄的遞歸上市,所以DirLister對象列表下的文件給定的根,如果某些變量是用虛線符號訪問的,它會返回一個DirLister,假定該屬性是根目錄下的一個文件夾。因此,如果我們試圖創造DirLister類步步將更加清晰

1-簡單DirLister僅列出其下

class DirLister(object): 
    def __init__(self, root): 
     self.root = root 
     self._list = os.listdir(self.root) 

2 - 我們簡單的李斯特文件/文件夾只列出文件中的一個水平深,如果我們想要獲取子文件夾下的文件管理器,我們可以使用obj.varname來掛接到使用varname調用的__getattr__。所以,如果我們的DIR-利斯特沒有屬性命名VARNAME我們假設用戶試圖訪問給定根目錄下該目錄中,所以我們創建另一個DirLister根爲root+subdirname

def __getattr__(self, name): 
    try: 
     var = super(DirLister).__getattr__(self, name) 
     return var 
    except AttributeError: 
     return DirLister(os.path.join(self.root, name)) 

注意:首先,我們檢查的基類因爲我們不想將所有變量訪問視爲子目錄訪問,所以如果沒有這樣的屬性,那麼我們爲子文件夾創建一個新的DirLister。

3-爲了提高代碼,使我們沒有列出所有文件夾,即使當用戶需要用戶沒有要求他們,我們只列出,因此一個load方法

def _load(self): 
    if self._list is not None: 
     return 
    self._list = os.listdir(self.root) # list root someway 

所以這種方法列出目錄如果還沒有列出,那麼應該在我們最終需要時調用它在打印列表

編輯:如要求由OP這裏是遞歸的另一種方法列出整棵樹,雖然我會強烈建議反對

import os 

class RecursiveDirLister(object): 
    def __init__(self, root): 
     self._sublist = [] 
     for folder in os.listdir(root): 
      self._sublist.append(folder) 
      path = os.path.join(root, folder) 
      if not os.path.isdir(path): 
       continue 
      # add it as attribute, assuming that dir-name is valid python varname 
      try: 
       sublister = RecursiveDirLister(path) 
      except OSError: 
       continue#ignore permission errors etc 
      setattr(self, folder, sublister) 

    def __str__(self): 
     return str(self._sublist) 

etc = RecursiveDirLister("/etc") 
print etc.fonts 

輸出:

['conf.avail', 'conf.d', 'fonts.conf', 'fonts.dtd'] 
0

不知道你在問什麼,但這會工作嗎?

for root,dirs,files in os.walk(/path/to/testdir/): 
    listers = dict((dir, directory_lister(dir)) for dir in dirs) 
    #now you can use: 
    listers['j'] 
    listers['k'] 
    listers['l']