2009-07-28 25 views
25

Szukam dobrego sposobu na uzyskanie względnych ścieżek plików i (pod) folderów w określonym folderze.Python - Uzyskaj względną ścieżkę dla wszystkich plików i podfolderów w katalogu

Dla mojego obecnego podejścia używam os.walk(). Działa, ale nie wydaje mi się "pytoniczny":

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) 

Jakieś inne sugestie?

Dzięki

+0

Co jest nie tak z os.walk? To pierwszorzędna część biblioteki. –

+0

Cóż, nie ma w tym nic złego. Ale nie wydawało się to tak "właściwe". Nie znam Pythona i jego standardowej biblioteki, to problem :) Ale wszystkie odpowiedzi dały kilka użytecznych sugestii, jak poprawić mój fragment. – vobject

Odpowiedz

50

Użyj os.path.relpath(). To jest dokładnie jego przeznaczenie.

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) 

Zauważ, że os.path.relpath() został dodany w Pythonie 2.6 i jest obsługiwane w systemie Windows i Unix.

+0

Do używania 'os.path.relpath()' zamiast manipulacji łańcuchami. –

+0

przy użyciu funkcji rozpoznawania list (która jest szybsza i bardziej pythonic): 'files = [os.path.relpath (os.path.join (dirpath, file), rootDir) dla (dirpath, dirnames, nazwy plików) w os.walk (rootDir) dla pliku w nazwach plików] ' – warownia1

2

Thats prawdopodobnie najlepszym sposobem, aby być uczciwym: można używać glob przejść pewną liczbę warstw w dół, ale jeśli trzeba, że ​​jest rekurencyjna trzeba walk.

1

Co robisz jest całkowitą rację i myślę, że powinno być wykonane w taki sposób, ale po prostu dla dobra alternatywa, tutaj jest próbą

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

myślę os.walk jest właściwym wyborem tutaj.
może root.replace(myFolder, "") powinien zmienić się na root.replace(myFolder, "", 1), aby uniknąć potencjalnego czegoś. wiesz.
Jeśli już dostałeś pliki i foldery (pod), os.path.commonprefix również warto obejrzeć.

+0

Dzięki za wspomnienie o trzecim parametrze replace(). – vobject

+2

Ponadto nie używaj '+ os.sep +', użyj '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

Można również użyć os.listdir() jeśli tylko szukają alternatywy dla rozwiązania.

Ale logika pozostanie taka sama: iteruj po plikach - jeśli katalog, iteruj przez podkatalog.

Powiązane problemy