Я написал программу, которая идет по каталогу, перемещает файлы в архив, с возможностью исключения определенных путей. Он работает, но он медленный.Идеи ускорить этот скрипт Python
Я не мог найти способ эффективно взаимодействовать с элементами в ttk.Treeview, поэтому он создает дерево и словарь, который использует индекс из 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()
Вы можете попытаться выяснить, что происходит медленно: ходить по каталогам или заполнять древовидную структуру. (Комментируйте строки, которые вставляются в дерево и видят, как изменяется время выполнения) –
Благодарим вас за ответ. Я попробовал ваше предложение, и, похоже, это ходьба, требующая времени. Я полагаю, это означает, что я ничего не могу с этим поделать? Есть ли лучший способ создать дерево каталогов с возможностью удаления каталогов из списка? Ну, мне не обязательно удалять каталоги из списка, мне просто нужно исключить их из процесса «Архив» – n30r3b3l
Вы можете измерить, где вы ДЕЙСТВИТЕЛЬНО потеряете время. Самый простой способ - поместить некоторый 't = time.time()' и напечатать 't-time()' где-то в решающих местах! И не стоит недооценивать накладные расходы самого заявления печати! для петель и длинных списков также возможны подозрения. Постарайтесь определить, где вы действительно теряете время, а затем возвращайтесь! Не стесняйтесь приспосабливать оригинальный вопрос (не меняйте его оригинальное направление), чтобы отразить процесс сужения! Хорошая охота! ;-) –