2013-08-15 11 views
5

Ho una semplice struttura di directory:os.walk() non restituisce quando gli viene chiesto di stampare dirpaths

rootdir\ 
    subdir1\ 
     file1.tif 
    subdir2\ 
     file2.tif 
    ... 
    subdir13\ 
     file13.tif 
    subdir14\ 
     file14.tif 

Se chiamo:

import os 

print os.listdir('absolute\path\to\rootdir') 

... allora ottengo quello che ci si expect:

['subdir1', 'subdir2', ... 'subdir13', 'subdir14'] 

La stessa cosa accade se chiamo os.listdir() su quelle sottodirectory. Per ognuno restituisce il nome del file in quella directory. Nessun problema lì.

E se mi chiamano:

import os 

for dirpath, dirnames, filenames in os.walk('absolute\path\to\rootdir'): 
    print filenames 
    print dirnames 

... tanto sono quello che vi aspettereste:

[] 
['subdir1', 'subdir2', ... 'subdir13', 'subdir14'] 
['file1.tif'] 
[] 
['file2.tif'] 
[] 
... 

ma ecco la stranezza. Quando chiamo:

import os 

for dirpath, dirnames, filenames in os.walk('absolute\path\to\rootdir'): 
    print filenames 
    print dirnames 
    print dirpath 

... non ritorna mai, mai. Anche se provassi:

print [each[0] for each in os.walk('absolute\path\to\roodir')] 

... o qualcosa del genere. Posso sempre stampare la seconda e la terza parte della tupla restituita da os.walk(), ma nel momento in cui provo a toccare la prima parte l'intera cosa si ferma.

Anche straniero, questo comportamento appare solo negli script lanciati usando la shell. L'interprete della riga di comando agisce normalmente. Sono curioso, cosa sta succedendo qui?

----- ----- EDIT codice vero e proprio:

ALLOWED_IMGFORMATS = [".jpg",".tif"] 

def getCategorizedFiles(pathname): 
    cats = [each[0] for each in os.walk(pathname) if not each[0] == pathname] 
    ncats = len(cats) 
    tree = [[] for i in range(ncats+1)] 
    for cat in cats: 
     catnum = int(os.path.basename(cat)) 
     for item in os.listdir(cat): 
      if not item.endswith('.sift') and os.path.splitext(item)[-1].lower() in ALLOWED_IMGFORMATS: 
       tree[catnum].append(cat + '\\' + item) 
    fileDict = {cat : tree[cat] for cat in range(1,ncats+1)} 
    return fileDict 

---- EDIT 2 ---- Un altro sviluppo. Come detto sopra, questo problema si verifica quando il codice è in script lanciati dalla shell. Ma non un guscio. Il problema esiste con Console 2, ma non con il prompt dei comandi di Windows. Esiste anche quando lo script viene lanciato da java (come ho originariamente incontrato il problema) in questo modo: http://www.programmersheaven.com/mb/python/415726/415726/invoking-python-script-from-java/?S=B20000

+0

Non so quale sia il problema. Ho appena copiato il codice in uno script, ho eseguito (sto usando 'python 2.7') e funziona esattamente come previsto – Anshul

+7

Attenzione a quelle barre rovesciate. Perché non usare le barre in avanti? Lavorano su Windows e non produrranno strani problemi di fuga. – user2357112

+0

Forse il problema è specifico per Windows.Hai provato a utilizzare un debugger per vedere quale codice è in esecuzione quando si blocca? – arghbleargh

risposta

1

Non mi sono mai fidato veramente di os.walk(). Scrivi le tue cose ricorsive. Non è difficile:

def contents(folder, l): # Recursive, returns list of all files with full paths 
    directContents = os.listdir(folder) 
    for item in directContents: 
     if os.path.isfile(os.path.join(folder, item)): 
      l.append(os.path.join(folder, item)) 
     else:contents(os.path.join(folder, item), l) 
    return l 
contents = contents(folder, []) 

contents sarà quindi un elenco di tutti i file con percorsi completi inclusi. Puoi usare os.split() se ti piace renderlo un po 'più facile da leggere.

Sapere come funziona elimina l'incertezza dell'uso di os.walk() nel codice, il che significa che sarete in grado di identificare se il problema nel vostro codice è realmente coinvolto con os.walk().

Se è necessario inserirli in un dizionario (poiché anche i dizionari hanno vantaggi di aliasing), è possibile ordinare i file in questo modo.

+0

+1 per self.walk (io uso il mio). Ma ottieni un -1 per "+". Utilizza os.join o anche meglio, "% s /% s"% (cartella, elemento). Metti un tempo semplice() e vedrai la differenza. directContents è molto più veloce se = ["% s /% s"% (cartella, x) per x in os.listdir (cartella)] – cox

+0

Abbastanza corretto. Buon suggerimento, e grazie per aver corretto, invece di ridurre il voto. – user2569332

+0

Vorrei prendere in considerazione la creazione di questo oggetto generatore anziché di una funzione che restituisce una lista. Nella maggior parte dei casi non è necessario creare l'intero elenco di file in una volta sola, e sarebbe facile fare 'lista (contenuto)' se lo si fa.Il generatore –

Problemi correlati