2009-01-30 6 views
13

Sto scrivendo uno script che deve spostare alcuni file, ma sfortunatamente non sembra che lo os.path giochi molto bene con l'internazionalizzazione. Quando ho file chiamati in ebraico, ci sono problemi. Ecco uno screenshot del contenuto di una directory:os.path di Python che si strozza sui nomi di file ebraici

alt text http://eli.thegreenplace.net/files/temp/hebfilenameshot.png

Ora considerano questo codice che va oltre i file in questa directory:

files = os.listdir('test_source') 

for f in files: 
    pf = os.path.join('test_source', f) 
    print pf, os.path.exists(pf) 

L'output è:

test_source\ex True 
test_source\joe True 
test_source\mie.txt True 
test_source\__()'''.txt True 
test_source\????.txt False 

Si noti come os.path.exists pensa che il file con nome in ebraico non esiste nemmeno? Come posso risolvere questo?

ActivePython 2.5.2 su Windows XP Home SP2

risposta

15

Hmm, dopo some digging sembra che quando la fornitura del sistema operativo.listdir una stringa unicode, questo funziona un pò:

files = os.listdir(u'test_source') 

for f in files: 

    pf = os.path.join(u'test_source', f) 
    print pf.encode('ascii', 'replace'), os.path.exists(pf) 

===>

test_source\ex True 
test_source\joe True 
test_source\mie.txt True 
test_source\__()'''.txt True 
test_source\????.txt True 

alcune importanti osservazioni qui:

  • di Windows XP (come tutti i derivati ​​NT) negozi tutto nomi di file in unicode
  • os.listdir (e funzioni simili, come os.walk) d essere passato una stringa unicode per funzionare correttamente con percorsi Unicode. Ecco una citazione dal link di cui sopra:

os.listdir(), che restituisce i nomi dei file, solleva una questione: se dovesse tornare la versione Unicode di nomi di file, o dovrebbe tornare stringhe a 8 bit contenente le versioni codificate? os.listdir() farà entrambe le cose, a seconda di se ha fornito il percorso della directory come stringa a 8 bit o una stringa Unicode . Se si passa una stringa Unicode come il percorso, i nomi dei file saranno decodificati utilizzando la codifica del file system e un elenco di stringhe Unicode sarà restituito, mentre passa un percorso di 8 bit torneranno le versioni a 8 bit del i nomi dei file.

  • E, infine, print vuole una stringa ASCII, non unicode, in modo che il percorso deve essere codificato in ASCII.
+0

non sembra essere schizzinosa su ascii in tutti gli ambienti. Vedi la mia risposta. La stampa – PEZ

+0

non ha problemi nella stampa di unicode: il problema potrebbe essere nella codifica stdout. Se la console è unicode, non ci sono problemi, altrimenti è richiesta una codifica esplicita. – piro

+0

È eccellente. Dovrebbe significare che puoi riportare i nomi di file normali su Windows se stampi su un file gestito con il set di codifica corretto. Il gestore di errori 'replace' mi segnala la sconfitta. =) – PEZ

3

Si presenta come un Unicode vs problema ASCII - os.listdir restituisce un elenco di stringhe ASCII.

Modifica: l'ho provato su Python 3.0, anche su XP SP2, e os.listdir semplicemente omesso i nomi di file ebraici invece di elencarli del tutto.

Secondo la documentazione, questo significa che era in grado di decodificarlo:

Nota che quando os.listdir() restituisce una lista di stringhe , i nomi dei file che non può essere decodificato correttamente vengono omessi piuttosto di generare UnicodeError.

+0

Immagino di poter provare, ma non mi sarà d'aiuto visto che al momento non riesco a passare a 3.0. Sono sicuro che ci dovrebbe essere una soluzione per 2.5 –

1

Funziona come un fascino con Python 2.5.1 su OS X:

subdir/bar.txt True 
subdir/foo.txt True 
subdir/עִבְרִית.txt True 

Forse che significa che questo ha a che fare con Windows XP in qualche modo?

EDIT: Ho provato anche con le stringhe Unicode per cercare di imitare il comportamento di Windows meglio:

for f in os.listdir(u'subdir'): 
    pf = os.path.join(u'subdir', f) 
    print pf, os.path.exists(pf) 

subdir/bar.txt True 
subdir/foo.txt True 
subdir/עִבְרִית.txt True 

Nel Terminal (OS X magazzino prompt dei comandi app) che è. Usando IDLE funzionava ancora, ma non stampava il nome file correttamente. Per assicurarsi che sia davvero unicode lì ho controllato:

>>>os.listdir(u'listdir')[2] 
u'\u05e2\u05b4\u05d1\u05b0\u05e8\u05b4\u05d9\u05ea.txt' 
+0

penso che abbia a che fare con il fatto che Windows memorizza tutti i nomi di file in Unicode. vedere la mia risposta parziale –

+0

Sulla mia macchina funziona anche con le stringhe Unicode. – PEZ

+0

curioso. se passo pf per stampare, lancia un'eccezione di codifica. deve aspettarsi ascii –

0

Un punto interrogativo è il simbolo più o meno universale visualizzato quando un carattere unicode non può essere rappresentato in una codifica specifica. Il tuo terminale o sessione interattiva sotto Windows probabilmente usa ASCII o ISO-8859-1 o qualcosa del genere. Quindi la stringa attuale è unicode, ma viene tradotta in ???? quando stampato sul terminale. Ecco perché funziona con PEZ, usando OSX.

+0

posso rendere unicode il display del terminale windoze? cosa fa OSX per mostrarlo bene? –