2009-06-27 14 views
17

Ich bin auf Python 2.6 für Windows.Python-Dateinamen in Unicode konvertieren

Ich benutze os.walk um einen Dateibaum zu lesen. Dateien können Nicht-7-Bit-Zeichen (z. B. "ae") in ihren Dateinamen enthalten. Diese sind in der internen String-Darstellung von Pythons kodiert.

Ich verarbeite diese Dateinamen mit Python-Bibliotheksfunktionen und das scheitert aufgrund falscher Codierung.

Wie kann ich diese Dateinamen in richtige (Unicode?) Python-Strings konvertieren?

Ich habe eine Datei "d: \ utest \ ü.txt". hat den Pfad als Unicode-Passing nicht:

>>> list(os.walk('d:\\utest')) 
[('d:\\utest', [], ['\xfc.txt'])] 
>>> list(os.walk(u'd:\\utest')) 
[(u'd:\\utest', [], [u'\xfc.txt'])] 
+2

funktioniert es: an Ihrem Ausgang Schauen !! Sowohl der Verzeichnisname u'd: \\ utest 'als auch der Dateiname u' \ xfc.txt 'werden als Unicode-Objekte u'blahblah' anstelle der vorherigen str-Objekte 'blahblah' dargestellt. Vielleicht verwirrend ist die Tatsache, dass der Umlaut mit \ xfc dargestellt wird, aber das ist bei str wie bei unicode gleich und hat nichts mit dem str/unicode Problem zu tun. –

+0

Vielleicht müssen Sie verstärken "scheitert aufgrund falscher Codierung" ... Was scheitert? Wie? Zeigt die vollständige Traceback- und Fehlermeldung an. –

Antwort

45

Wenn Sie eine Unicode-Zeichenfolge zu os.walk() passieren, werden Sie Unicode Ergebnisse erhalten:

>>> list(os.walk(r'C:\example'))   # Passing an ASCII string 
[('C:\\example', [], ['file.txt'])] 
>>> 
>>> list(os.walk(ur'C:\example'))  # Passing a Unicode string 
[(u'C:\\example', [], [u'file.txt'])] 
+0

mit der Ausnahme, dass wenn ein Dateiname undecodable ist dann [Sie können eine Bytezeichenfolge anstelle von Unicode in Python 2 erhalten] (http://StackOverflow.com/a/22314324/4279) – jfs

1

os.walk nicht angegeben ist immer os.listdir zu verwenden, aber es ist auch nicht aufgelistet, wie Unicode gehandhabt wird. Allerdings hat os.listdir sagen:

Changed in version 2.3: On Windows NT/2k/XP and Unix, if path is a Unicode object, the result will be a list of Unicode objects. Undecodable filenames will still be returned as string objects.

Ist einfach ein Unicode-Argument Arbeit für Sie mit?

for dirpath, dirnames, filenames in os.walk(u"."): 
    print dirpath 
    for fn in filenames: 
    print " ", fn 
1

Nein, sie sind nicht in Pythons internen String-Darstellung codiert, es gibt keine solche Sache. Sie sind in der Codierung des Betriebssystems/Dateisystems codiert. Das Übergeben von Unicode funktioniert jedoch für os.walk.

Ich weiß nicht, wie os.walk sich verhält, wenn Dateinamen nicht entschlüsselt werden können, aber ich nehme an, dass Sie eine Zeichenfolge zurück erhalten, wie mit os.listdir(). In diesem Fall werden Sie später wieder Probleme haben. Außerdem akzeptiert nicht die gesamte Python 2.x-Standardbibliothek Unicode-Parameter ordnungsgemäß, daher müssen Sie sie möglicherweise als Zeichenfolgen kodieren. Das Problem kann also woanders liegen, aber Sie werden bemerken, wenn das der Fall ist. ;-)

Wenn Sie mehr Kontrolle über die Decodierung benötigen, können Sie nicht immer eine Zeichenfolge übergeben und dann einfach mit filename = filename.decode() wie üblich dekodieren.

+1

Nicht meine Down-Abstimmung, aber: Wenn Sie nicht tun Wissen Sie, nehmen Sie nicht an. –

+1

Oh, entschuldigen Sie, dass ich detaillierter bin als die anderen Antworten und mögliche Probleme mit der Lösung aufbringe. –

+1

+1 für eine vernünftige Annahme, aber immer noch explizit, dass es eine Annahme ist. Ein weiteres +1 (wenn ich könnte), um der Diskussion einen Mehrwert zu verleihen. – RichieHindle

2

ein direkterer Weg könnte sein, das folgende zu versuchen - finden Sie die Kodierung Ihres Dateisystems, und konvertieren Sie das dann in Unicode. zum Beispiel

unicode_name = unicode(filename, "utf-8", errors="ignore") 

zu dem anderen Weg zu gehen,

unicode_name.encode("utf-8") 
6

Ich wurde nach einer Lösung für Python 3.0 + suchen. Wird es hier aufstellen, wenn jemand anderes es braucht.

rootdir = r'D:\COUNTRY\ROADS\' 
fs_enc = sys.getfilesystemencoding() 
for (root, dirname, filename) in os.walk(rootdir.encode(fs_enc)): 
    # do your stuff here, but remember that now 
    # root, dirname, filename are represented as bytearrays 
+0

Dieses funktioniert für mich mindestens – ramdaz

+0

@ramdaz 1. Wie der Syntax-Highlighter zeigt: Sie sollten nicht ungerade Schrägstrich vor dem Schlusskurs verwenden. Es ist ein 'SyntaxError' in Python. 2. Der Code in der Antwort hat "Bytes" an "os.walk()" übergeben und daher werden die Dateinamen als Bytes erzeugt. Sie sollten stattdessen Unicode verwenden ('' encode() 'call). OP ist verwirrt. Übergeben von Unicode ist das Richtige unter Windows. – jfs

+0

Scheint die Arbeit mit Python 3.5 beendet zu haben: 'TypeError: os.scandir() unterstützt keinen Bytes Pfad unter Windows, benutze stattdessen Unicode ' – koppor

3
os.walk(unicode(root_dir, 'utf-8')) 
Verwandte Themen