manejar cadenas de código no ascii en python

Es realmente confuso manejar el código no-ascii en python. ¿Alguien puede explicar?

Estoy intentando leer un archivo de texto plano y reemplazar todos los caracteres no alfabéticos con espacios.

Tengo una lista de personajes:

ignorelist = ('!', '-', '_', '(', ')', ',', '.', ':', ';', '"', '\'', '?', '#', '@', '$', '^', '&', '*', '+', '=', '{', '}', '[', ']', '\\', '|', '', '/', u'—') 

para cada token que tengo, sustituyo cualquier char en ese token con espacio llamando

  for punc in ignorelist: token = token.replace(punc, ' ') 

note que hay un carácter de código no ignorelist al final de ignorelist : u'—'

Cada vez que mi código encuentra ese carácter, se bloquea y dice:

 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 

Intenté declarar la encoding agregando # -*- coding: utf-8 -*- en la parte superior del archivo, pero aún no funciona. Alguien sabe por qué? ¡Gracias!

Está utilizando Python 2.x, e intentará convertir automáticamente unicode s y plain str s, pero a menudo falla con caracteres que no son ASCII.

No debes mezclar unicode sy str s juntos. Usted puede pegarse a unicode s:

 ignorelist = (u'!', u'-', u'_', u'(', u')', u',', u'.', u':', u';', u'"', u'\'', u'?', u'#', u'@', u'$', u'^', u'&', u'*', u'+', u'=', u'{', u'}', u'[', u']', u'\\', u'|', u'<', u'>', u'/', u'—') if not isinstance(token, unicode): token = token.decode('utf-8') # assumes you are using UTF-8 for punc in ignorelist: token = token.replace(punc, u' ') 

o use solo str s llanos (note el último):

 ignorelist = ('!', '-', '_', '(', ')', ',', '.', ':', ';', '"', '\'', '?', '#', '@', '$', '^', '&', '*', '+', '=', '{', '}', '[', ']', '\\', '|', '<', '>', '/', u'—'.encode('utf-8')) # and other parts do not need to change 

Al codificar manualmente tu u'—' en una str , Python no tendrá que intentarlo por sí mismo.

Le sugiero que use unicode todo su progtwig para evitar este tipo de errores. Pero si sería demasiado trabajo, puede utilizar el último método. Sin embargo, tenga cuidado cuando llame a algunas funciones en la biblioteca estándar o en módulos de terceros.

# -*- coding: utf-8 -*- solo le dice a Python que su código está escrito en UTF-8 (o obtendrá un SyntaxError ).

Su entrada de archivo no es utf-8. Entonces cuando golpeas ese carácter Unicode, tu entrada barfs en la comparación porque ve tu entrada como ascii.

Trate de leer el archivo con esto en su lugar.

 import codecs f = codecs.open("test", "r", "utf-8")