2012-01-22 57 views
7

Tôi đang cố gắng quét đĩa cứng của mình cho các tệp jpg và mp3.os.path.isfile không hoạt động như mong đợi

Tôi đã viết tập lệnh sau hoạt động nếu tôi chuyển cho nó một thư mục có tệp trong thư mục gốc nhưng không trả về bất cứ thứ gì nếu tôi chuyển nó vào thư mục gốc.

Tôi mới sử dụng Python nên rất thích sự trợ giúp.

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 
+1

Bạn đang cố tìm kiếm đệ quy thông qua các thư mục? – alexmherrmann

+1

Có rất nhiều mã trong hàm này. Điều gì làm cho bạn chắc chắn rằng đó là lời kêu gọi để 'os.path.isfile (f)' mà là đi awry? Ngoài ra hàm 'filterfiles()' của bạn có thể 'trả về ext trong tệpFilter', vì bạn có lỗi đánh máy ở đó. – Johnsyweb

+0

Vâng tôi. Tôi đoán đây là vấn đề như khi tôi bước qua nó được xây dựng trong chức năng trả về false khi f là một tập tin thực sự. Tôi có thể là cách tắt. Bạn không chắc chắn nơi bạn nhìn thấy lỗi đánh máy? – gmoorevt

Trả lời

9

Ah có.

Bạn đang gọi số os.path.isfile(f) trong đó f là tên tệp trong số path. Bạn cần phải cung cấp đường dẫn tuyệt đối. Nếu thực sự, cuộc gọi này là cần thiết (nó phải luôn trả về True).

Hãy thử thay đổi của bạn cho vòng lặp để:

qualified_filenames = (os.path.join(path, filename) for filename in fnames) 
    for f in qualified_filenames: 

Và bạn nên được thiết lập!

Ngoài ra, các cuộc gọi đến os.chdir() là không cần thiết.

Và, như tôi đã gợi ý trong các ý kiến, filterfiles nên trông như thế này:

def filterfiles(f): 
    ext = os.path.splitext(f)[1][1:] 
    return ext in fileFilter 

(Bạn bỏ lỡ một return).

+1

Cảm ơn! Điều này đã làm các trick. Cảm ơn đã giúp đỡ. – gmoorevt

0

Tôi tin hằng os.chdir() cuộc gọi ở đây là làm phức tạp chương trình của bạn (và thậm chí có thể vít lên như thế nào os.walk() công trình).

tôi đã sao chép ví dụ đẹp hơn như thế nào để làm việc với các tên đường dẫn mà không có sự thay đổi thư mục từ the Python documentation:

# Delete everything reachable from the directory named in "top", 
# assuming there are no symbolic links. 
# CAUTION: This is dangerous! For example, if top == '/', it 
# could delete all your disk files. 
import os 
for root, dirs, files in os.walk(top, topdown=False): 
    for name in files: 
     os.remove(os.path.join(root, name)) 
    for name in dirs: 
     os.rmdir(os.path.join(root, name)) 

Bạn sử dụng os.path.join(root, name) khi bạn đã chọn một name từ files.

2

Không liên quan trực tiếp đến câu hỏi của bạn, nhưng đây là một số mẹo Python hiện đại nói chung kể từ khi bạn là người mới đến Python:

os.stat(f)[stat.ST_SIZE] 

có thể được viết như

os.stat(f).st_size 

if filesBySize.has_key(size): 
    a = filesBySize[size] 
else: 
    a = [] 
    filesBySize[size] = a 

được viết tốt hơn là:

a = filesBySize.setdefault(size, []) 
+1

hoặc thậm chí, ['filesBySize = defaultdict (danh sách); ... filesBySize [size] .append (f) '] (http://stackoverflow.com/a/8959455/4279) không có' a'. – jfs

3

filesBySize là nhóm khá bất thường. Bạn có thể di chuyển nó ra ngoài findfiles() chức năng:

#!/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 

Không có nhu cầu sử dụng os.chdir(), nó là đủ để gọi os.path.join(path, f).

Các vấn đề liên quan