2009-07-28 12 views
25

Sto cercando un buon modo per ottenere percorsi relativi di file e (sotto) cartelle all'interno di una cartella specifica.Python - Ottieni il percorso relativo di tutti i file e le sottocartelle in una directory

Per il mio approccio attuale sto usando os.walk(). Funziona ma non mi sembra "pitonico":

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) 

Altri suggerimenti?

Grazie

+0

Cosa c'è di sbagliato in os.walk? È una parte di prima classe della biblioteca. –

+0

Suppongo che non ci sia nulla di sbagliato. Ma non sembrava così "giusto". Non ho familiarità con Python e la sua libreria standard, questo è un problema :) Ma tutte le risposte hanno fornito alcuni suggerimenti utili su come migliorare il mio frammento di codice. – vobject

risposta

50

Utilizzare os.path.relpath(). Questo è esattamente il suo uso previsto.

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) 

Nota che os.path.relpath() è stato aggiunto in Python 2.6 ed è supportato su Windows e Unix.

+0

Risale all'utilizzo di 'os.path.relpath()' invece della manipolazione delle stringhe. –

+0

utilizzando la comprensione delle liste (che è più veloce e più pitone): 'files = [os.path.relpath (os.path.join (dirpath, file), rootDir) per (dirpath, dirnames, nomi di file) in os.walk (rootDir) per il file nei nomi dei file] ' – warownia1

2

Questo è probabilmente il modo migliore per essere onesti: è possibile utilizzare glob di andare un certo numero di strati verso il basso, ma se avete bisogno di essere ricorsivo bisogna walk.

1

Quello che state facendo è perfettamente ragione e penso che dovrebbe essere fatto in questo modo, ma solo per il gusto di alternativa, qui è un tentativo

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

Penso os.walk è la scelta giusta qui.
forse root.replace(myFolder, "") dovrebbe cambiare a root.replace(myFolder, "", 1) per evitare potenziale sth. sai.
Se si dispone già dei file e delle (sotto) cartelle, vale la pena dare un'occhiata anche a os.path.commonprefix.

+0

Grazie per aver menzionato il terzo parametro per replace(). – vobject

+2

Inoltre, non usare '+ os.sep +', usare '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

È inoltre possibile utilizzare os.listdir() se sono solo alla ricerca di un'alternativa alla soluzione.

Ma fondamentalmente la logica rimarrà la stessa: scorrere i file - se la directory, scorrere la sottodirectory.

Problemi correlati