Python''s os.path asfixiando nombres de archivos hebreos
internationalization hebrew (4)
Funciona como un encanto usando Python 2.5.1 en OS X:
subdir/bar.txt True
subdir/foo.txt True
subdir/עִבְרִית.txt True
Tal vez eso significa que esto tiene que ver con Windows XP de alguna manera?
EDITAR: También probé con cadenas de caracteres unicode para intentar imitar mejor el comportamiento de Windows:
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
En la Terminal (aplicación de símbolo del sistema OS x stock) que es. El uso de IDLE todavía funcionaba pero no imprimía el nombre de archivo correctamente. Para asegurarme de que realmente es unicode allí, verifiqué:
>>>os.listdir(u''listdir'')[2]
u''/u05e2/u05b4/u05d1/u05b0/u05e8/u05b4/u05d9/u05ea.txt''
Estoy escribiendo un script que tiene que mover algunos archivos, pero desafortunadamente no parece que os.path
juegue muy bien con la internacionalización. Cuando tengo archivos nombrados en hebreo, hay problemas. Aquí hay una captura de pantalla de los contenidos de un directorio:
texto alternativo http://eli.thegreenplace.net/files/temp/hebfilenameshot.png
Ahora considere este código que pasa por los archivos en este directorio:
files = os.listdir(''test_source'')
for f in files:
pf = os.path.join(''test_source'', f)
print pf, os.path.exists(pf)
El resultado es:
test_source/ex True
test_source/joe True
test_source/mie.txt True
test_source/__()''''''.txt True
test_source/????.txt False
Observe cómo os.path.exists
cree que el archivo con nombre hebreo ni siquiera existe? ¿Cómo puedo arreglar esto?
ActivePython 2.5.2 en Windows XP Home SP2
Hmm, después de excavar , parece que al suministrar os.listdir una cadena Unicode, esto funciona:
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
Algunas observaciones importantes aquí:
- Windows XP (como todos los derivados de NT) almacena todos los nombres de archivo en Unicode
-
os.listdir
(y funciones similares, comoos.walk
) deben pasar una cadena Unicode para funcionar correctamente con rutas Unicode. Aquí hay una cita del enlace mencionado anteriormente:
os.listdir (), que devuelve nombres de archivos, plantea un problema: ¿debería devolver la versión Unicode de los nombres de archivo, o debería devolver cadenas de 8 bits que contienen las versiones codificadas? os.listdir () hará ambas cosas, dependiendo de si proporcionó la ruta del directorio como una cadena de 8 bits o una cadena Unicode. Si pasa una cadena Unicode como ruta, los nombres de archivo se decodificarán utilizando la codificación del sistema de archivos y se devolverá una lista de cadenas Unicode, mientras que pasar una ruta de 8 bits devolverá las versiones de 8 bits de los nombres de archivo.
- Y, por último,
print
quiere una cadena ascii, no unicode, por lo que la ruta debe codificarse en ascii.
Parece un problema Unicode vs ASCII: os.listdir
devuelve una lista de cadenas ASCII.
Editar: Lo intenté en Python 3.0, también en XP SP2, y os.listdir
simplemente omitió los nombres de archivo en hebreo en lugar de enumerarlos.
De acuerdo con los documentos, esto significa que no fue capaz de decodificarlo:
Tenga en cuenta que cuando os.listdir () devuelve una lista de cadenas, los nombres de archivo que no se pueden decodificar correctamente se omiten en lugar de aumentar UnicodeError.
Un signo de interrogación es el símbolo más o menos universal que se muestra cuando un carácter Unicode no se puede representar en una codificación específica. Su sesión terminal o interactiva en Windows probablemente esté usando ASCII o ISO-8859-1 o algo así. Entonces, ¿la cadena real es unicode, pero se traduce a ???? cuando se imprime en la terminal. Es por eso que funciona para PEZ, utilizando OSX.