Realmente me gustaría que mi aplicación Python trate exclusivamente con cadenas Unicode internamente. Esto me ha ido bien últimamente, pero me he encontrado con un problema con las rutas de manejo. La API POSIX para sistemas de archivos no es Unicode, por lo que es posible (y de hecho algo común) que los archivos tengan nombres "indecodificables": nombres de archivos que no están codificados en la codificación establecida del sistema de archivos.¿Cómo manejar nombres de archivo indecodificables en Python?
En Python, esto se manifiesta como una mezcla de unicode
y str
objetos devueltos desde os.listdir()
.
>>> os.listdir(u'/path/to/foo')
[u'bar', 'b\xe1z']
En ese ejemplo, el carácter '\xe1'
está codificado en Latin-1 o algo por el estilo, incluso cuando la (hipotética) de sistema de archivos informa sys.getfilesystemencoding() == 'UTF-8'
(en UTF-8, que carácter serían los dos bytes '\xc3\xa1'
). Por esta razón, obtendrá UnicodeError
s por todas partes si intenta utilizar, por ejemplo, os.path.join()
con rutas Unicode, porque el nombre de archivo no se puede decodificar.
El Python Unicode HOWTO ofrece este consejo sobre nombres de ruta Unicode:
Tenga en cuenta que en la mayoría de ocasiones, las API Unicode debe ser utilizado. Las API de bytes solo deben usarse en sistemas donde los nombres de archivos indecodificables pueden estar presentes, es decir, sistemas Unix.
Porque me importa principalmente de los sistemas Unix, ¿significa esto que debería reestructurar mi programa a tratar sólo con cadenas de bytes de caminos? (De ser así, ¿cómo puedo mantener la compatibilidad con Windows?) ¿O hay otras formas mejores de tratar con nombres de archivos indecodificables? ¿Son lo suficientemente raros "en la naturaleza" como para pedirles a los usuarios que renombren sus malditos archivos?
(Si lo mejor es tratar simplemente con cadenas de bytes internamente, tengo una pregunta de seguimiento:? ¿Cómo almaceno cadenas de bytes en SQLite para una columna, manteniendo el resto de los datos de las cadenas Unicode como amigables)
¡Gracias! No sabía sobre este PEP. Es una solución bastante inteligente. – adrian