2009-07-28 15 views
25

Estoy buscando una buena forma de obtener rutas de acceso relativas de archivos y (sub) carpetas dentro de una carpeta específica.Python: obtenga la ruta relativa de todos los archivos y subcarpetas en un directorio

Para mi enfoque actual estoy usando os.walk(). Está funcionando pero no me parece "pitónico":

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) 

¿Alguna otra sugerencia?

Gracias

+0

¿Qué pasa con os.walk? Es una parte de primera clase de la biblioteca. –

+0

Bueno, no hay nada de malo en eso, supongo. Pero no parecía tan "correcto". No estoy familiarizado con Python y su biblioteca estándar, ese es el problema :) Pero todas las respuestas dieron algunas sugerencias útiles sobre cómo mejorar mi fragmento. – vobject

Respuesta

50

Use os.path.relpath(). Este es exactamente su 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) 

Tenga en cuenta que os.path.relpath() se añadió en Python 2.6 y es compatible con Windows y Unix.

+0

Hasta para usar 'os.path.relpath()' en lugar de manipulación de cadenas. –

+0

usando la comprensión de listas (que es más rápido y más pythonic): 'files = [os.path.relpath (os.path.join (dirpath, archivo), rootDir) para (dirpath, dirnames, nombres de archivos) en os.walk (rootDir) para archivo en nombres de archivo] ' – warownia1

2

Eso es probablemente la mejor manera para ser honesto: se puede usar para ir glob un cierto número de capas de abajo, pero si usted lo necesita ser recursivo que tiene que walk.

1

Lo que está haciendo es perfectamente correcto y creo que se debe hacer de esa manera, pero sólo por el bien de la alternativa, aquí es un intento

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

Creo os.walk es la elección correcta aquí.
tal vez root.replace(myFolder, "") debe cambiar a root.replace(myFolder, "", 1) para evitar la posibilidad de algo. ya sabes.
Si ya obtiene los archivos y las (sub) carpetas, os.path.commonprefix también merece la pena.

+0

Gracias por mencionar el tercer parámetro para replace(). – vobject

+2

Además, no use '+ os.sep +', use '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

También puede utilizar os.listdir() si usted está buscando una alternativa a la solución.

Pero, básicamente, la lógica seguirá siendo la misma: itere sobre los archivos - si el directorio, itera a través del subdirectorio.

Cuestiones relacionadas