2009-07-28 41 views
25

Tôi đang tìm kiếm một cách tốt để có được đường dẫn tương đối của tệp và thư mục con (phụ) trong một thư mục cụ thể.Python - Nhận đường dẫn tương đối của tất cả các tệp và thư mục con trong một thư mục

Đối với phương pháp hiện tại của tôi, tôi đang sử dụng os.walk(). Nó hoạt động nhưng có vẻ như không phải là "pythonic" đối với tôi:

myFolder = "myfolder" 
fileSet = set() # yes, I need a set() 

for root, dirs, files in os.walk(myFolder): 
    for fileName in files: 
     fileSet.add(root.replace(myFolder, "") + os.sep + fileName) 

Bất kỳ đề xuất nào khác?

Cảm ơn

+0

Có vấn đề gì với os.walk? Đó là một phần hạng nhất của thư viện. –

+0

Vâng, không có gì sai với nó tôi đoán. Nhưng nó không có vẻ như vậy "đúng". Tôi không quen thuộc với python và thư viện chuẩn của nó, đó là vấn đề :) Nhưng tất cả các câu trả lời đều đưa ra một số gợi ý hữu ích về cách cải thiện đoạn trích của tôi. – vobject

Trả lời

50

Sử dụng os.path.relpath(). Đây chính xác là mục đích sử dụng của nó.

import os 
rootDir = "myfolder" 
fileSet = set() 

for dir_, _, files in os.walk(rootDir): 
    for fileName in files: 
     relDir = os.path.relpath(dir_, rootDir) 
     relFile = os.path.join(relDir, fileName) 
     fileSet.add(relFile) 

Lưu ý rằng os.path.relpath() được thêm vào Python 2.6 và được hỗ trợ trên Windows và Unix.

+0

Sử dụng 'os.path.relpath()' thay vì thao tác chuỗi. –

+0

sử dụng tính năng đọc danh sách (nhanh hơn và nhiều hơn nữa): 'files = [os.path.relpath (os.path.join (dirpath, file), rootDir) cho (dirpath, dirnames, filenames) trong os.walk (rootDir) cho tệp trong tên tệp] ' – warownia1

2

Thats có lẽ là cách tốt nhất để được trung thực: bạn có thể sử dụng glob đi một số lượng nhất định các lớp xuống, nhưng nếu bạn cần nó để được đệ quy bạn phải walk.

1

Những gì bạn đang làm là hoàn toàn đúng và tôi nghĩ nên được thực hiện theo cách đó, nhưng chỉ vì lợi ích của thay thế, đây là một nỗ lực

import os 

def getFiles(myFolder): 
    old = os.getcwd() 
    os.chdir(myFolder) 

    fileSet = set() 

    for root, dirs, files in os.walk(""): 
     for f in files: 
      fileSet.add(os.path.join(root, f)) 

    os.chdir(old) 
    return fileSet 
3

Tôi nghĩ os.walk là sự lựa chọn ngay tại đây.
có thể root.replace(myFolder, "") phải thay đổi thành root.replace(myFolder, "", 1) để tránh bị hỏng hóc. bạn biết.
Nếu bạn đã nhận được các tệp và (phụ) thư mục, os.path.commonprefix cũng đáng xem xét.

+0

Cảm ơn bạn đã đề cập đến tham số thứ ba cho hàm replace(). – vobject

+2

Ngoài ra, không sử dụng '+ os.sep +', sử dụng 'os.path.join'. –

8
myFolder = "myfolder" 
fileSet = set() 

for root, dirs, files in os.walk(myFolder): 
    for fileName in files: 
     fileSet.add(os.path.join(root[len(myFolder):], fileName)) 
1

Bạn cũng có thể sử dụng os.listdir() nếu bạn chỉ tìm kiếm giải pháp thay thế.

Nhưng về cơ bản logic sẽ vẫn như cũ: lặp qua các tệp - nếu thư mục, lặp qua thư mục con.

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