我尝试在网络驱动器.xlsm
上找到所有O:\
个文件(并获取其统计信息),前提是它们不在名为Test
的文件夹中。我使用os.walk
并切换到scandir.walk
,因为它更快。我现在只受网络速度的限制。这段代码似乎在脚本和网络驱动器之间有很多交互。我的代码如下。有没有办法加快速度,可能使用批处理文件?我在Windows上。
from scandir import scandir, walk
import sys
def subdirs(path):
for path, folders, files in walk(path):
if 'Test' not in path:
for sub_files in scandir(path):
if '.xlsm' in sub_files.path:
yield subfiles.stat()
for i in subdirs('O:\\'):
print i
答案 0 :(得分:3)
您通过walk
隐式地对每个路径进行双重扫描,然后再次明确重新scandir
无理由返回path
walk
。 walk
已经返回了files
,因此内部循环可以通过仅使用它给出的内容来避免双重扫描:
def subdirs(path):
for path, folders, files in walk(path):
for file in files:
if '.xlsm' in file:
yield os.path.join(path, file)
要解决更新的问题,您可能希望复制现有的scandir.walk
代码并修改它以返回list
代替DirEntry
s list
s名称,或为您的特定需求编写类似的特殊代码;无论哪种方式,这将允许您避免双重扫描,同时保持scandir
特殊的低开销行为。例如:
def scanwalk(path, followlinks=False):
'''Simplified scandir.walk; yields lists of DirEntries instead of lists of str'''
dirs, nondirs = [], []
for entry in scandir.scandir(path):
if entry.is_dir(follow_symlinks=followlinks):
dirs.append(entry)
else:
nondirs.append(entry)
yield path, dirs, nondirs
for dir in dirs:
for res in scanwalk(dir.path, followlinks=followlinks):
yield res
然后你可以像这样替换你对walk
的使用(我还添加了用Test
修剪目录的代码,因为它们下面的所有目录和文件都会被原始代码拒绝,但你仍然不必要地穿越他们):
def subdirs(path):
# Full prune if the path already contains Test
if 'Test' in path:
return
for path, folders, files in scanwalk(path):
# Remove any directory with Test to prevent traversal
folders[:] = [d for d in folders if 'Test' not in d.name]
for file in files:
if '.xlsm' in file.path:
yield file.stat() # Maybe just yield file to get raw DirEntry?
for i in subdirs('O:\\'):
print i
顺便说一句,您可能需要仔细检查是否已为scandir
,_scandir
正确安装/构建了C加速器。如果未构建_scandir
,则scandir
模块会使用ctypes
提供回退实现,但它们会明显变慢,这可以解释性能问题。尝试在交互式Python会话中运行import _scandir
;如果它引发ImportError
,那么你就没有加速器,所以你正在使用缓慢的后备实现。