Convertir los nombres de archivo de Python a Unicode

Estoy en Python 2.6 para Windows.

Yo uso os.walk para leer un árbol de archivos. Los archivos pueden tener caracteres que no sean de 7 bits (por ejemplo, “ae” en alemán) en sus nombres de archivo. Estos están codificados en la representación de cadena interna de Pythons.

Estoy procesando estos nombres de archivo con las funciones de la biblioteca Python y eso falla debido a una encoding incorrecta.

¿Cómo puedo convertir estos nombres de archivo a cadenas de python adecuadas (Unicode?)?

Tengo un archivo “d: \ utest \ ü.txt”. Pasar la ruta como unicode no funciona:

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

Si pasas una cadena Unicode a os.walk() , obtendrás resultados de Unicode:

 >>> 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'])] 

Estaba buscando una solución para Python 3.0+. Lo pondré aquí en caso de que alguien más lo necesite.

 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 
 os.walk(unicode(root_dir, 'utf-8')) 

una forma más directa podría ser intentar lo siguiente: buscar la encoding del sistema de archivos y luego convertirla a Unicode. por ejemplo,

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

ir por el otro lado,

 unicode_name.encode("utf-8") 

os.walk no está especificado para usar siempre os.listdir , pero tampoco se muestra cómo se maneja Unicode. Sin embargo, os.listdir dice:

Cambiado en la versión 2.3: En Windows NT / 2k / XP y Unix, si la ruta es un objeto Unicode, el resultado será una lista de objetos Unicode. Los nombres de archivo que no se pueden decodificar se devolverán como objetos de cadena.

¿Simplemente usar un argumento Unicode funciona para ti?

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

No, no están codificados en la representación de cadena interna de Pythons, no hay tal cosa. Están codificados en la encoding del sistema operativo / sistema de archivos. Pasando en unicode funciona para os.walk sin embargo.

No sé cómo se comporta os.walk cuando los nombres de archivos no se pueden decodificar, pero asumo que obtendrá una cadena de vuelta, como con os.listdir (). En ese caso volverás a tener problemas más tarde. Además, no toda la biblioteca estándar de Python 2.x aceptará los parámetros Unicode correctamente, por lo que es posible que tenga que codificarlos como cadenas de todos modos. Por lo tanto, el problema puede estar en otro lugar, pero notará si ese es el caso. 😉

Si necesita más control de la deencoding, no siempre puede pasar una cadena y luego decodificarla con filename = filename.decode () como siempre.