5

tengo este código en Google App Engine (SDK Python):string.maketrans de Python funciona en casa, pero falla en Google App Engine

from string import maketrans 

intab = u"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ".encode('latin1') 
outtab = u"aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn".encode('latin1') 
logging.info(len(intab)) 
logging.info(len(outtab)) 
trantab = maketrans(intab, outtab) 

Cuando ejecuto el código en la consola interactiva no tengo ningún problema, pero cuando intento en GAE me sale el siguiente error:

aumentar ValueError, "maketrans argumentos deben tener la misma longitud" ValueError: maketrans argumentos deben tener la misma longitud INFO 2009-12-03 20: 04: 02.904 dev_appserver. py: 3038] "POST/backendsavenew HTTP/1.1" 500 - INFORMACIÓN 2009-12-03 20: 08: 37,649 admi n.py:112] 106 INFO 2009-12-03 20: 08: 37,651 admin.py:113] 53 ERROR 2009-12-03 20: 08: 37,653 init .py: 388] los argumentos de maketrans deben tener misma longitud

No puedo entender por qué el tamaño de la tarjeta ha duplicado. El archivo python con el código se guarda como UTF-8.

Gracias de antemano por cualquier ayuda.

Respuesta

14

string.maketrans y string.translate no funcionan para cadenas Unicode. Su llamada al string.maketrans convertirá implícitamente el Unicode que le dio a una codificación como utf-8. En utf-8å ocupa más espacio que ASCII a. string.maketrans ve len(str(argument)) que es diferente para sus dos cadenas.

Hay una traducción Unicode, pero para su caso de uso (convertir Unicode en ASCII porque alguna parte de su sistema no puede tratar con Unicode) debe usar http://pypi.python.org/pypi/Unidecode. Unidecode es muy inteligente sobre la transliteración de caracteres Unicode a ASCII sensible, cubriendo muchos más caracteres que en su ejemplo.

Debe guardar su código de Python como utf-8, pero asegúrese de agregar la magia para que Python no tenga que asumir que utilizó la codificación predeterminada del sistema. Esta línea debe ser la primera o segunda línea de los archivos de Python:

# -*- coding: utf-8 -*- 

Hay muchas ventajas para el procesamiento de texto como Unicode en lugar de cadenas binarias. Esta es la forma de Unicode para hacer lo que está tratando de hacer:

intab = u"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ" 
outtab = u"aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn" 
trantab = dict((ord(a), b) for a, b in zip(intab, outtab)) 
translated = intab.translate(trantab) 
translated == outtab # True 

Véase también Where is Python's "best ASCII for this Unicode" database?

Véase también How do I get str.translate to work with Unicode strings?

+0

Prefiero no agregar un nuevo paquete a GAE para resolverlo, pero veré el código de Unidecode. Gracias. –

+0

# - * - codificación: utf-8 - * - lo resolvió. Gracias. –

+0

También necesitaba eliminar algunos caracteres. Cambié el código a "modo Unicode" y agregué algunas conversiones a None en el diccionario. –

1

Tal vez usted podría utilizar la codificación ISO-8859-1 para su archivo en lugar de utf-8

# -*- coding: iso-8859-1 -*- 
from string import maketrans 
import logging 

intab = "ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ" 
outtab = "aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn" 
logging.info(len(intab)) 
logging.info(len(outtab)) 
trantab = maketrans(intab, outtab) 

Recuerde seleccionar iso-8859-1 en su editor de texto mientras guarda este archivo de origen python.

+0

Me pregunto por qué he votado negativamente. El código se ejecuta en google appengine (acabo de probarlo) y hace lo que se supone que debe hacer. –

+0

Lamentablemente, la pregunta es incorrecta.La solución correcta es hacer el procesamiento de texto en Unicode y evitar 'str.translate' por completo. – joeforker