Usted pidió explicaciones, pero algunos de los fenómenos inexplicables sin su ayuda.
Cuerdas (A) en archivos XLS creados por Excel 97 en adelante se codifican en Latin1 si es posible de otra manera en UTF16LE. Cada cuerda lleva una bandera que indica cuál fue utilizada. Anteriormente supera las cadenas codificadas de acuerdo con la "página de códigos" del usuario. En cualquier caso, xlrd produce objetos Unicode. La codificación del archivo es de interés solo cuando el archivo XLS ha sido creado por un software de terceros que omite la página de códigos o miente al respecto. Consulte la sección Unicode en la parte frontal de los documentos xlrd.
(B) fenómeno inexplicable:
este código:
bcw = csv.writer(bc,csv.excel,b.encoding)
provoca el siguiente error con Python 2.5, 2.6 y 3.1: TypeError: expected at most 2 arguments, got 3
- esto es sobre lo que cabe esperar dado los documentos en csv.writer; está esperando un objeto similar a un archivo seguido de (1) nada (2) un dialecto o (3) uno o más parámetros de formato. Le diste un dialecto y csv.writer no tiene argumento de codificación, así que splat. ¿Qué versión de Python estás usando? ¿O no copió/pegó el guión que realmente ejecutó?
(C) Fenómenos inexplicables alrededor de rastreo y lo que el infractor de datos real fue:
"the_script.py", line 40, in <module>
this_row.append(str(s.cell_value(row,col)))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xed' in position 5: ordinal not in range(128)
primer lugar, no es un str() en la línea de código erróneo, que no estaba en el guión simplificado - ¿verdad no copiar/pegar la secuencia de comandos que realmente ejecutó? En cualquier caso, no debe usar str en general, no obtendrá la precisión completa en sus flotadores; simplemente deja que el módulo csv los convierta.
En segundo lugar, se dice "" "El valor es parece ser cada vez colgó en que es '516-777316' - el texto en la hoja de Excel original es '516 a 7.773.167' (con un 7 en el extremo) "" "--- es difícil imaginar cómo se pierde el 7 al final. Me gustaría usar algo como esto para saber exactamente cuál era la problemática de datos:
try:
str_value = str(s.cell_value(row, col))
except:
print "row=%d col=%d cell_value=%r" % (row, col, s.cell_value(row, col))
raise
Eso% r le ahorra escribir cell_value=%s ... repr(s.cell_value(row, col))
... la repr() produce una representación inequívoca de sus datos. Aprenderlo. Úselo.
¿Cómo llegaste a "516-777316"?
EN TERCER lugar, el mensaje de error en realidad se está quejando sobre un carácter unicode u '\ xed' en el desplazamiento 5 (es decir, el sexto carácter). U + 00ED es LETRA I MINÚSCULA LATINA CON AGUDA, y no hay nada como eso en "516-7773167"
CUARTO lugar, la ubicación del error parece ser un objetivo en movimiento - dijiste en un comentario sobre uno de los soluciones: "El error está en bcw.writerow". ¿Huh?
(D) Por qué aparece ese mensaje de error (con str(): str(a_unicode_object)
intenta convertir el objeto Unicode en un objeto str y en ausencia de cualquier información de codificación utiliza ascii, pero tiene datos que no son ascii, así que splat. Tenga en cuenta que su objetivo es producir un archivo csv codificado en utf8, pero su script simplificado no menciona utf8 en ninguna parte.
(E) "" "... en la celda (fila, col)) (egscell en lugar de s.cell_value)
todo el documento se escribe sin errores. El resultado no es particularmente deseable (texto: u'516-7773167 ') ''"
Eso está sucediendo porque el escritor csv está llamando el método de tu teléfono objeto __str__
, y esto produce <type>:<repr(value)>
que puede ser útil para la depuración, pero como no se dice tan grande en su archivo csv.
(F) La solución de Alex Martelli es genial porque te ayudó. Sin embargo, debes leer la sección de la clase Cell en los documentos xlrd: los tipos de celda son texto, número, booleano, fecha, error, en blanco y vacío. yo Tiene fechas, va a querer formatearlas como fechas, no como números, por lo que no puede usar isinstance() (y es posible que no desee que la llamada funcione de todos modos) ... esto es lo que el Cell.ctype
atributo y Sheet.cell_type()
y Sheet.row_types()
métodos son para.
(G) UTF8 no es Unicode. UTF16LE no es Unicode. UTF16 no es Unicode ... y la idea de que cadenas individuales desperdiciarían 2 bytes cada una en una lista de materiales UTF16 es demasiado absurda para que incluso MS la contemple :-)
(H) Lectura adicional (aparte de los documentos xlrd):
http://www.joelonsoftware.com/articles/Unicode.html
http://www.amk.ca/python/howto/unicode
sería útil para ver todo el rastreo, para saber que está tirando el error. – Christopher
No hay mucho más que ver: Archivo "the_script.py ", línea 40, en this_row.append (str (s.cell_value (row, col))) UnicodeEncodeError: el códec 'ascii' no puede codificar el carácter u '\ xed' en la posición 5: ordinal not in range (128) –
anschauung
con "salida de Excel en Unicode", parece que el sentido de "salida de Excel en UTF-16". Unicode define un codespace, que está representado por los diferentes sistemas de codificación, como UTF-8 o UTF-16. – Svante