SyntaxError: carácter no ASCII '\ xa3' en el archivo cuando la función devuelve '£'


284

Digamos que tengo una función:

def NewFunction():
    return '£'

Quiero imprimir algunas cosas con un signo de libra delante e imprime un error cuando intento ejecutar este programa, se muestra este mensaje de error:

SyntaxError: Non-ASCII character '\xa3' in file 'blah' but no encoding declared;
see http://www.python.org/peps/pep-0263.html for details

¿Alguien puede informarme cómo puedo incluir un signo de libra en mi función de devolución? Básicamente lo estoy usando en una clase y es dentro de la '__str__'parte que se incluye el signo de libra.


43
¿Incluso leíste el PEP al que te vinculaste? Describe cuál es el problema y cómo solucionarlo.
murgatroid99

2
"¿Alguien puede informarme cómo puedo incluir un signo de libra en mi función de devolución?" Bueno, el mensaje de error dice "ver python.org/peps/pep-0263.html para más detalles"; tal vez deberías comenzar por ahí?
Karl Knechtel

55
@ murgatroid99 Esto es lo que usted y cuando escribo esto faltan otros 27: Sí, por supuesto, leeré el PEP. Nivel de dificultad: obtuve esto tratando de ejecutar / bin / sh contra un contenedor acoplable. No estoy tratando abiertamente de ejecutar Python. Entonces, todo lo que PEP me va a decir es cómo arreglar el código de Python que no estoy tratando de ejecutar y no escribí. Esperaba más contexto de StackOverflow, en vez de eso obtuve petulancia. :( La búsqueda adicional mostró la respuesta real: stackoverflow.com/questions/38992850/… - observe cómo el PEP hizo exactamente cero para ayudar.
Mark Allen

@MarkAllen: en su respuesta vinculada, el mensaje de error indica que Python está tratando de interpretar "/ bin / bash": es algo fácil de pasar por alto, pero nada en esta pregunta indica que tenga que ver con un acoplador o un contenedor, por lo que el consejo aquí, como has encontrado, no se aplica a tu problema, no es presunción, es solo que hay contexto en tu problema, eso no está presente aquí.
Tanantish

@tanantish mantengo lo que dije. Recibí el error en la pregunta. En lugar de dar información útil a las personas con las que se reunió, "¿Leyó siquiera el PEP al que se vinculó?" y, "Bueno, el mensaje de error dice ver (bla), ¿quizás deberías comenzar allí?" <- Esas respuestas no son útiles. No estoy seguro de por qué estamos teniendo esta discusión.
Mark Allen el

Respuestas:


368

Recomiendo leer ese PEP que te da el error. El problema es que su código está tratando de usar la codificación ASCII, pero el símbolo de libra no es un carácter ASCII. Intente usar la codificación UTF-8. Puede comenzar colocando # -*- coding: utf-8 -*-en la parte superior de su archivo .py. Para avanzar, también puede definir codificaciones cadena por cadena en su código. Sin embargo, si está tratando de poner el signo de libra literal en su código, necesitará una codificación que lo admita para todo el archivo.


306

Agregar las dos líneas siguientes se sentó en la parte superior de mi script .py funcionó para mí (la primera línea era necesaria):

#!/usr/bin/env python
# -*- coding: utf-8 -*- 

Tengo el mismo problema y mi Python es 2.7.11. Después de agregar la segunda línea # -*- coding: utf-8 -*-a la parte superior del archivo, resolvió el problema.
granizo

2
La primera línea es hacer que el archivo py sea ejecutable en * nix. Realmente no está relacionado con esta pregunta.
cmd

57

Primero agregue la # -*- coding: utf-8 -*-línea al comienzo del archivo y luego úsela u'foo'para todos sus datos unicode no ASCII:

def NewFunction():
    return u'£'

o use la magia disponible desde Python 2.6 para hacerlo automático:

from __future__ import unicode_literals

12
Si lo tiene # -*- coding: utf-8 -*-, no necesita prefijar sus cadenas Unicode conu
Daniel Lee

@plaes ¿qué pasa si está en una variable? ejemplo leyendo un archivo? No puedo usar uVariable, ¿cómo lo hago?
Skizo-ozᴉʞS

1
@DanielLee Excepto que esto no es cierto. # -*- coding: utf-8 -*-seguido de print 'błąd'generará basura, mientras print u'błąd'funciona.
Przemek D

@DanielLee Lo que dijo Przemek D. Poner literales UTF-8 en su código fuente de esa manera generalmente no es una buena idea, y puede conducir a un comportamiento no deseado, especialmente en Python 2. Si los literales no son ASCII de 7 bits puros, deberían ser Unicode reales, no UTF-8, así que en Python 2 deberías poner el uprefijo en tales literales. En Python 3, las cadenas simples son Unicode de todos modos, pero el uprefijo está permitido en versiones recientes de Python 3 para que sea un poco más fácil escribir código que se comporte correctamente en Python 2 y 3.
PM 2Ring

12

El mensaje de error te dice exactamente qué está mal. El intérprete de Python necesita conocer la codificación del carácter no ASCII.

Si desea devolver U + 00A3 , puede decir

return u'\u00a3'

que representa este carácter en ASCII puro mediante una secuencia de escape Unicode. Si desea devolver una cadena de bytes que contiene el byte literal 0xA3, eso es

return b'\xa3'

(donde en Python 2 el bes implícito; pero explícito es mejor que implícito).

El PEP vinculado en el mensaje de error le indica exactamente cómo decirle a Python "este archivo no es ASCII puro; aquí está la codificación que estoy usando". Si la codificación es UTF-8, eso sería

# coding=utf-8

o el compatible con Emacs

# -*- encoding: utf-8 -*-

Si no sabe qué codificación utiliza su editor para guardar este archivo, examínelo con algo como un editor hexadecimal y algunas búsquedas en Google. El desbordamiento de pilatag tiene una página de información de etiquetas con más información y algunos consejos para la solución de problemas.

En muchas palabras, fuera del rango ASCII de 7 bits (0x00-0x7F), Python no puede ni debe adivinar qué cadena representa una secuencia de bytes. https://tripleee.github.io/8bit#a3 muestra 21 posibles interpretaciones para el byte 0xA3 y eso es solo de las codificaciones heredadas de 8 bits; pero también podría ser el primer byte de una codificación de varios bytes. Pero, de hecho, supongo que en realidad estás usando Latin-1, por lo que deberías tener

# coding: latin-1

como la primera o segunda línea de su archivo fuente. De todos modos, sin saber qué carácter se supone que representa el byte, un humano tampoco podría adivinar esto.

Una advertencia: coding: latin-1definitivamente eliminará el mensaje de error (porque no hay secuencias de bytes que técnicamente no están permitidas en esta codificación), pero podría producir un resultado completamente incorrecto cuando el código se interpreta si la codificación real es otra cosa. Realmente tiene que conocer la codificación del archivo con total certeza cuando declara la codificación.


Esta es una adaptación de una respuesta anterior mía a una pregunta duplicada: stackoverflow.com/a/50829958/874188
tripleee

Python 3 está predeterminado en UTF-8 para los archivos de origen, y de todos modos probablemente debería usar UTF-8 para todo en estos días. utf8everywhere.org
tripleee

8

Agregar las siguientes dos líneas en el script resolvió el problema para mí.

# !/usr/bin/python
# coding=utf-8

Espero eso ayude !


2

Probablemente esté intentando ejecutar el archivo Python 3 con el intérprete Python 2. Actualmente (a partir de 2019), el pythoncomando predeterminado es Python 2 cuando ambas versiones están instaladas, en Windows y en la mayoría de las distribuciones de Linux.

Pero en caso de que realmente esté trabajando en un script Python 2, una solución aún no mencionada en esta página es volver a guardar el archivo en la codificación UTF-8 + BOM, que agregará tres bytes especiales al inicio del archivo, lo harán informar explícitamente al intérprete de Python (y su editor de texto) sobre la codificación del archivo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.