2013-12-13 43 views
1

我寫了一個程序,走過一個目錄,將文件移動到一個檔案,能夠排除某些路徑。它正在工作,但速度很慢。想法加快這個Python腳本

我找不到與ttk.Treeview中的項目進行高效交互的方法,因此它構建樹和字典,它使用樹視圖中的索引作爲鍵和目錄名稱作爲值。

關於如何加快這個過程的任何想法?

現在它需要大約3分鐘以建立目錄樹在一個體面的大小的文件夾,另有3分鐘就好在測試模式下打印新的位置。

我的代碼:

import tkFileDialog, os, ttk, checkage, logging, shutil 
from Tkinter import * 
import profile 

source = '' 
dest = '' 

#Build UI 
class Master(Frame): 

    def __init__(self, parent): 
     Frame.__init__(self, parent)   
     self.parent = parent   
     self.initUI() 

    def initUI(self): 
     self.parent.title("pyRchive") 
     self.pack(fill=BOTH, expand=1) 

     lSrc = Label(self, text="Choose Source Directory") 
     lSrc.grid(column = 0, row = 0, padx = 2, pady = 2, sticky=NW) 
     eSrc = Entry(self, bd=5, width=50) 
     eSrc.grid(column = 0, row = 0, padx = 5, pady = 5, sticky=SW) 
     bSrc = Button(self, text="Browse...", command=lambda: choosedir(eSrc)) 
     bSrc.grid(column = 1, row = 0, padx = 5, pady = 5, sticky=SW) 
     bAdd = Button(self, text="Add", command=lambda: buildTree(self)) 
     bAdd.grid(column = 0, row = 1, padx = 5, pady = 5, sticky=NW) 
     lDest = Label(self, text="Choose Destination Directory") 
     lDest.grid(column = 0, row = 2, padx = 5, pady = 5, sticky=NW) 
     eDest = Entry(self, bd=5, width=50) 
     eDest.grid(column = 0, row = 2, padx = 2, pady = 5, sticky=SW) 
     bDest = Button(self, text="Browse...", command=lambda: choosedir(eDest)) 
     bDest.grid(column = 1, row = 2, padx = 2, pady = 5, sticky=SW) 
     bExec = Button(self, text="Archive Files", command=lambda: archive(self)) 
     bExec.grid(column = 0, row = 3, padx = 2, pady = 5, sticky=NW) 
     bDel = Button(self, text="Remove Directory", command=lambda: deldir(self)) 
     bDel.grid(column = 1, row = 9, padx = 5, pady = 5, sticky=SE) 
     tree = ttk.Treeview(self, height=20) 
     tree.column("#0", width=400) 
     tree.grid(column = 2, row = 0, padx = 5, pady = 5, rowspan=10, sticky=NSEW) 

     ysb = ttk.Scrollbar(orient=VERTICAL, command=tree.yview) 
     tree['yscroll'] = ysb.set 
     ysb.grid(in_=self, column = 3, row=0, sticky=NS, rowspan=10) 
     rootlst = {} 

     #Display Directory when bBrowse is pressed 
     def choosedir(text): 
      logging.info('Adding Directory to %s' %(text)) 
      rootfolder = tkFileDialog.askdirectory() 
      text.insert(0, os.path.abspath(rootfolder)) 

     #Build the Directory Tree 
     def buildTree(self): 
      logging.info('Building Directory Tree') 
      rootfolder = eSrc.get() 
      global source 
      source = rootfolder 
      create_root(rootfolder) 
      for root, dirs, files in os.walk(rootfolder):   
       for i in rootlst: 
        if os.path.split(root)[0] == rootlst[i]: 
         logging.info('Adding %s to directory tree' %(root)) 
         rt = tree.insert(i, 'end', text='\\' + os.path.basename(root)) 
         rootlst[rt] = root 
         break 
      eSrc.delete(0, 'end') 
      #print tree.get_children() 

     #Make root level of tree 
     def create_root(root): 
      logging.info('Adding the root directory (%s) to the tree' %(root)) 
      rt = tree.insert('', 'end', text=root) 
      rootlst[rt] = root 

     #Archive the files in the selected directories 
     def archive(self): 
      logging.info('Starting Archive Process') 
      dest = eDest.get() 
      if os.path.isdir(source): 
       for i in rootlst:      
        for fname in os.listdir(rootlst[i]): 
         oldname = os.path.join(rootlst[i], fname) 
         if os.path.isfile(oldname): 
          logging.info('fname is a file') 
          if checkage.check(oldname): 
           logging.info('fname is older than 3 years') 
           newname = oldname.replace(source, dest) 
           logging.info('Moving %s to %s' %(oldname, newname)) 
           print newname 

      else: 
       pass 
       #put a message box here for invalid Destination Directory 

     #Remove Directories from tree 
     def deldir(self): 
      selected = tree.selection() 
      sel = [] 
      for i in selected: 
       path = rootlst[i] 
       print 'Delete ', tree.item(i, 'text'), ' and all sub directories' 
       print path 

       tree.delete(i) 
       for i in rootlst: 
        if rootlst[i].startswith(path): 
         sel.append(i) 
       for i in sel: 
        del rootlst[i] 
      for i in rootlst: 
       print i 

def main(): 
    logging.basicConfig(filename='pyRchive.log', format='%(asctime)s %(message)s', 
         datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO) 
    logging.info('Starting Application') 
    root = Tk() 
    app = Master(root) 
    root.mainloop() 



if __name__ == '__main__': 
    main() 
+0

你可以嘗試找出什麼是慢的:漫步目錄或填充樹視圖。 (註釋掉插入到樹中的行並查看運行時如何改變) –

+0

感謝您的回覆。我嘗試了你的建議,似乎是需要時間的行走。我想這意味着我對此無能爲力?有沒有更好的方法來構建一個能夠從列表中刪除目錄的目錄樹?那麼我不一定需要從列表中刪除目錄,我只需要將它們從「存檔」過程中排除 – n30r3b3l

+0

您可以測量您真正放鬆時間的位置。最簡單的方法是在關鍵位置放置一些't = time.time()'並打印't-time()'!並且不要低估print語句本身的開銷! for循環和長列表也是可能的嫌疑犯。嘗試確定你真正的時間在哪裏,然後回來!隨意適應你原來的問題(不改變它的原始方向),以反映你的縮小過程!好狩獵! ;-) –

回答

1

不要使用os.walk;相反,使用os.listdir獲得第一級條目,然後 建立你的樹,只在需要時(用戶選擇目錄)你執行必需的目錄 另一os.listdir並顯示其內容,等

你做根據用戶的動作對目錄內容進行懶惰的評估,而不是預先製作一個大的結構。