我写了一个小程序,基本上搜索网络驱动器中的一些mat文件。我使用的是Python3.6,所以我可以访问os.scandir()
命令,这个命令比os.walk().
更好
但我面临一个奇怪的问题,当我第一次运行程序时需要花费大量时间来获取数据。但是当我在几个小时后运行相同的程序时,它的工作速度非常快。
任何人都能解释一下为什么会造成这种情况吗?以下是我的代码。
注意:我的Internet速度非常好,因此网络驱动器的映射是无缝的。
class WorkThread(QObject):
def scantree(self,path):
try:
for entry in scandir(path):
if entry.is_dir(follow_symlinks=False):
yield from self.scantree(entry.path) # see below for Python 2.x
else:
yield entry
except FileNotFoundError:
print("Excluded file path")
def searchFiles(self):
start=time.time()
ui.progressBar.setValue(0)
usePATH='V:\Messdatenbank_Powertrain' # Location to the network drive
os.chdir(usePATH)
fileLevels = 0
i=0
k=0
tableSize = ui.tableView.width()
ui.tableView.setColumnWidth(4, int(tableSize/4) + 30 )
ui.tableView.setColumnWidth(3, int(tableSize/4) + 300 )
for entry in self.scantree(usePATH):
if entry.name.endswith('COMPARE.mat') and 'MATLAB_NVH_TOOL' not in entry.path and 'old' not in entry.path and 'MESSDATENBANK' not in entry.path and 'old_' not in entry.path:
ui.progressBar.setValue(0)
i=i+1
fileLevels=0# if 'COMPARE.mat' in f and not 'MIN' in f and not 'MAX' in f / if 'COMPARE.mat' in f ) # if 'COMPARE.mat' in f and not 'MIN' in f and not 'MAX' in f
fileLevels=(entry.path.split('\\')) # Split path string at all '/'
#print (fileLevels)
t_row=[QtGui.QStandardItem(str(fileLevels[2])),QtGui.QStandardItem( str(fileLevels[3])),QtGui.QStandardItem(str(fileLevels[4])),QtGui.QStandardItem(str(fileLevels[len(fileLevels)-1])),QtGui.QStandardItem(str(entry.path))]
ui.tableView.model().appendRow(t_row)
ui.tableView.model().layoutChanged.emit()
fileLevels.remove(fileLevels[len(fileLevels)-1])
tmp_file_levels='\\'.join(fileLevels)
ui.files.append(tmp_file_levels) # All files path stored here
ui.file_loc_name.append(entry.path)
ui.progressBar.setValue(50)
# Implement try catch blocks
if str(fileLevels[2]) not in ui.clusterlist:
ui.clusterlist.append(str(fileLevels[2]))
if str(fileLevels[2]) not in ui.enginedict:
ui.enginedict[str(fileLevels[2])]=[str(fileLevels[3])]
else:
if str(fileLevels[3]) not in ui.enginedict[str(fileLevels[2])]:
ui.enginedict[str(fileLevels[2])].append(str(fileLevels[3]))
if str(fileLevels[3]) not in ui.measurementdict:
ui.measurementdict[str(fileLevels[3])]=[str(fileLevels[4])]
else:
if str(fileLevels[4]) not in ui.measurementdict[str(fileLevels[3])]:
ui.measurementdict[str(fileLevels[3])].append(str(fileLevels[4]))
ui.progressBar.setValue(100)
QApplication.processEvents()
else:
ui.label_7.setText(str(i))
ui.tableView.model().layoutChanged.emit()
ui.progressBar.setValue(0)
end=time.time()
print(end-start)
ui.label_2.setText('Update Complete')
ui.pushButton.setEnabled(False)
print(str(len(ui.files)))
ui.tableView.resizeColumnToContents (2)
ui.comboBox.setEnabled(True)
ui.label_7.setText(str(len(ui.files)))
ui.comboBox.clear()
ui.comboBox.addItems(["--Select Cluster--"])
ui.comboBox.addItems(ui.clusterlist)
ui.progressBar.setValue(100)
QApplication.processEvents()
ui.pushButton_2.setEnabled(True)
ui.pushButton_24.setEnabled(True)
答案 0 :(得分:2)
python.org PEP 471 -- os.scandir()描述了os.scandir
os.scandir
- 这个新功能增加了有用的功能 将os.walk()的速度提高2-20倍
首次执行期间由缓存数据导致的第一次执行和下次执行之间的差异。
有关缓存的说明
DirEntry对象相对愚蠢 - 名称和路径 属性显然总是被缓存,以及is_X和stat方法 缓存其值(立即在Windows上通过FindNextFile,和 首次使用POSIX系统通过统计系统调用),永远不会 从系统中重新获取。
出于这个原因,DirEntry对象旨在被使用和抛出 迭代后离开,不存储在长寿命数据结构中 方法一次又一次地被召唤。
如果开发者想要"刷新"行为(例如,观看一个 文件的大小改变),他们可以简单地使用pathlib.Path对象,或者调用 常规的os.stat()或os.path.getsize()函数变得新鲜 每次调用时来自操作系统的数据。