La comstackción de Python 2.7 en Sublime Text 3 no imprime el carácter ‘\ uFFFD’

El problema.

Estoy usando Python 2.7 build en Sublime Text 3 y tengo un problema con la impresión.
En algunos casos, obtengo una salida bastante confusa para '\uFFFD' – el 'REPLACEMENT CHARACTER' .


Por ejemplo:

 print u'\ufffd' # should be ' ' - the 'REPLACEMENT CHARACTER' print u'\u0061' # should be 'a' ----------------------------------------------------- [Finished in 0.1s] 

Después de la inversión del pedido:

 print u'\u0061' print u'\ufffd' ----------------------------------------------------- a   [Finished in 0.1s] 

Así, Sublime puede imprimir el carácter ”, pero por alguna razón no lo hace en el primer caso.
Y la dependencia de la salida en el orden de las declaraciones parece bastante extraña.


El problema con el reemplazo de caracteres conduce a un comportamiento de impresión muy impredecible en general.
Por ejemplo, quiero imprimir bytes decodificados con reemplazo de error:

 cp1251_bytes = '\xe4\xe0' # 'да' in cp1251 print cp1251_bytes.decode('utf-8', errors='replace') -----------------------------------------------------    [Finished in 0.1s] 

Vamos a reemplazar los bytes:

 cp1251_bytes = '\xed\xe5\xf2' # 'нет' in cp1251 print cp1251_bytes.decode('utf-8', errors='replace') ----------------------------------------------------- [Finished in 0.1s] 

Y añada una statement impresa más:

 cp1251_bytes = '\xed\xe5\xf2' # 'нет' in cp1251 print cp1251_bytes.decode('cp1251') print cp1251_bytes.decode('utf-8', errors='replace') ----------------------------------------------------- нет     [Finished in 0.1s] 

A continuación se muestra la ilustración de la implementación de otros casos de prueba:

introduzca la descripción de la imagen aquí


Resumiendo , existen los siguientes patrones en el comportamiento de impresión descrito:

  • depende del número par / impar de caracteres '\ufffd' en la statement de impresión
  • Depende del orden de las declaraciones impresas.
  • Depende de la ejecución de comstackción específica

  • Mis preguntas:

  • ¿Por qué pasó esto?
  • ¿Como solucionar el problema?

  • Mi archivo Python 2.7 de construcción sublime:

     { "cmd": ["C:\\_Anaconda3\\envs\\python27\\python", "-u", "$file"], "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", "selector": "source.python", "env": {"PYTHONIOENCODING": "utf-8"} } 

    Con Python 2.7 instalado por separado de Anaconda, el comportamiento es exactamente el mismo.

    He reproducido su problema y he encontrado una solución que funciona en mi plataforma de todos modos: elimine la -u de su opción de configuración de configuración de cmd .

    No estoy 100% seguro de por qué funciona, pero parece ser una interacción deficiente como resultado de que la consola interpreta un flujo de datos sin búfer que contiene caracteres de varios bytes. Esto es lo que he encontrado:

    • La opción -u cambia la salida de Python a sin búfer
    • Este problema no es en absoluto específico para el carácter de reemplazo. He tenido un comportamiento similar con otros personajes como “あ” (U + 3042).
    • Similares resultados malos ocurren con otras codificaciones. Si se configura "env": {"PYTHONIOENCODING": "utf-16be"} se print u'\u3042' 0B .

    El último ejemplo con la encoding establecida en UTF-16BE ilustra lo que creo que está sucediendo. La consola recibe un byte a la vez porque la salida no tiene búfer. Entonces recibe el byte 0x30 primero. La consola luego determina que esto no es válido como UTF-16BE y en su lugar decide recurrir a ASCII y, por lo tanto, genera un 0 . Por supuesto, recibe el siguiente byte justo después y sigue la misma lógica para generar B

    Con la encoding UTF-8, la consola recibe bytes que posiblemente no pueden interpretarse como ASCII, por lo que creo que la consola está haciendo un mejor trabajo para interpretar correctamente el flujo no guardado en el búfer, pero aún se encuentra con las dificultades que su pregunta Señala.

    Edit-1 – Usando UTF8 con BOM

    Parece que BOM se vuelve importante en el caso de las ventanas. Así que necesitas usar la configuración de comstackción de abajo.

     { "cmd": ["F:\\Python27-14\\python", "-u", "$file"], "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", "selector": "source.python", "env": { "PYTHONIOENCODING": "utf_8_sig" }, } 

    Después de eso funciona correctamente para mí también en windows

    crear configuraciones

    salida correcta

    Respuesta original

    Revisé el problema y no enfrenté lo mismo en Python 2.7 con texto Sublime. El único cambio fue que tuve que agregar # -*- coding: utf-8 -*- en la parte superior del archivo. Lo que parece la parte faltante en esta pregunta.

     # -*- coding: utf-8 -*- print u'\u0061' # should be 'a' print u'\ufffd' # should be ' ' - the 'REPLACEMENT CHARACTER' 

    Después de eso la reversión no tiene impacto.

    imprimir 1

    imprimir 2

    Puedes ver más detalles sobre este encabezado requerido en

    ¿Por qué declarar Unicode por cadena en Python?

    A continuación se muestra un resumen del enlace anterior.

    Cuando especifica # -*- coding: utf-8 -*- , le está diciendo a Python que el archivo fuente que ha guardado es utf-8 . El valor predeterminado para Python 2 es ASCII (para Python 3 es utf-8 ). Esto solo afecta a cómo el intérprete lee los caracteres en el archivo.