os.path.isfile 不按预期工作
我正在尝试扫描我的硬盘,找出jpg和mp3文件。
我写了一个脚本,如果我给它一个包含文件的目录,它能正常工作,但如果我给它根目录,它就什么都不返回。
我刚开始学习Python,所以希望能得到一些帮助。
def findfiles(dirname,fileFilter):
filesBySize = {}
def filterfiles(f):
ext = os.path.splitext(f)[1][1:]
if ext in fileFilter:
return True
else:
False
for (path, dirs, fnames) in os.walk(dirname):
if len(fileFilter)>0:
fnames = filter(filterfiles,fnames)
d = os.getcwd()
os.chdir(dirname)
for f in fnames:
if not os.path.isfile(f) :
continue
size = os.stat(f)[stat.ST_SIZE]
if size < 100:
continue
if filesBySize.has_key(size):
a = filesBySize[size]
else:
a = []
filesBySize[size] = a
a.append(os.path.join(dirname, f))
# print 'File Added: %s' %os.path.join(dirname,f)
_filecount = _filecount + 1
os.chdir(d)
return filesBySize
4 个回答
2
虽然这和你的问题不完全相关,但因为你是Python新手,这里有一些现代Python的小技巧:
os.stat(f)[stat.ST_SIZE]
可以写成
os.stat(f).st_size
而且
if filesBySize.has_key(size):
a = filesBySize[size]
else:
a = []
filesBySize[size] = a
更好的写法是:
a = filesBySize.setdefault(size, [])
3
filesBySize
这个分组方式有点特别。你可以把它放到 findfiles()
函数外面:
#!/usr/bin/env python
import os
import stat
import sys
from collections import defaultdict
def findfiles(rootdir, extensions=None, minsize=100):
"""Find files with given `extensions` and larger than `minsize`.
If `extensions` is None then don't filter on extensions.
Yield size, filepath pairs.
"""
extensions = tuple(extensions) if extensions is not None else extensions
for path, dirs, files in os.walk(rootdir):
if extensions is not None: # get files with given extensions
files = (f for f in files if f.endswith(extensions))
for f in files:
f = os.path.join(path, f)
try:
st = os.stat(f)
except os.error:
continue # skip
if stat.S_ISREG(st.st_mode): # isfile
if st.st_size > minsize:
yield st.st_size, f
rootdir = sys.argv[1] # get it from command-line
files_by_size = defaultdict(list)
for size, f in findfiles(rootdir, ['.mp3', '.jpg']):
files_by_size[size // (1<<20)].append((size, f)) # group in 1M buckets
import pprint
pprint.pprint(dict(files_by_size)) # pretty print
其实不需要使用 os.chdir()
,只要调用 os.path.join(path, f)
就可以了。
12
哦,明白了。
你在调用 os.path.isfile(f)
,这里的 f
是文件名,位于 path
里面。你需要提供一个绝对路径。如果这个调用确实是必要的(它应该总是返回 True
)。
试着把你的循环改成这样:
qualified_filenames = (os.path.join(path, filename) for filename in fnames)
for f in qualified_filenames:
这样就可以了!
另外,调用 os.chdir()
是不需要的。
还有,正如我在评论中提到的,filterfiles
应该更像这样:
def filterfiles(f):
ext = os.path.splitext(f)[1][1:]
return ext in fileFilter
(你漏掉了一个 return
)。