SyntaxError: caractère non ASCII '\ xa3' dans le fichier lorsque la fonction retourne '£'


284

Disons que j'ai une fonction:

def NewFunction():
    return '£'

Je veux imprimer des trucs avec un signe dièse devant et il affiche une erreur lorsque j'essaie d'exécuter ce programme, ce message d'erreur s'affiche:

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

Quelqu'un peut-il m'informer sur la façon dont je peux inclure un signe dièse dans ma fonction de retour? Je l'utilise essentiellement dans une classe et c'est dans la '__str__'partie que le signe dièse est inclus.


43
Avez-vous même lu le PEP auquel vous êtes lié? Il décrit quel est le problème et comment le résoudre.
murgatroid99

2
"Quelqu'un peut-il m'informer sur la façon dont je peux inclure un signe dièse dans ma fonction de retour." Eh bien, le message d'erreur dit "voir python.org/peps/pep-0263.html pour plus de détails"; vous devriez peut-être commencer par là?
Karl Knechtel

5
@ murgatroid99 Voici ce que vous et au moment où je tape 27 autres sont manquants: Oui bien sûr je vais lire le PEP. Niveau de difficulté: j'ai obtenu cela en essayant d'exécuter / bin / sh contre un conteneur docker. Je n'essaie pas ouvertement d'exécuter Python. Donc, tout ce que le PEP va me dire, c'est comment réparer le code python que je n'essaie pas d'exécuter et que je n'ai pas écrit. J'espérais plus de contexte de StackOverflow, j'ai eu la suffisance à la place. :( Une recherche plus approfondie a révélé la réponse réelle: stackoverflow.com/questions/38992850/… - remarquez comment le PEP a fait exactement zéro pour aider.
Mark Allen

@MarkAllen - dans votre réponse liée, le message d'erreur indique que python essaie d'interpréter "/ bin / bash" - c'est certes quelque chose de facile à ignorer, mais rien dans cette question n'indique qu'il s'agit de docker ou d'un conteneur, donc les conseils ici comme vous l'avez trouvé ne s'applique pas à votre problème - ce n'est pas de la suffisance, c'est juste qu'il y a du contexte dans votre problème, ce n'est pas présent ici.
tanantish le

@tanantish Je maintiens ce que j'ai dit. J'ai eu l'erreur dans la question. Plutôt que de donner des informations utiles aux personnes rencontrées, "Avez-vous même lu le PEP auquel vous êtes lié?" et "Eh bien, le message d'erreur dit voir (bla), peut-être que vous devriez commencer par là?" <- Ces réponses ne sont pas utiles. Je ne sais pas pourquoi nous avons cette discussion.
Mark Allen

Réponses:


368

Je recommanderais de lire le PEP que l'erreur vous donne. Le problème est que votre code essaie d'utiliser le codage ASCII, mais le symbole dièse n'est pas un caractère ASCII. Essayez d'utiliser le codage UTF-8. Vous pouvez commencer par mettre # -*- coding: utf-8 -*-en haut de votre fichier .py. Pour être plus avancé, vous pouvez également définir des encodages chaîne par chaîne dans votre code. Cependant, si vous essayez de mettre le signe dièse littéral dans votre code, vous aurez besoin d'un encodage qui le prend en charge pour l'ensemble du fichier.


306

L'ajout des deux lignes suivantes se trouvait en haut de mon script .py a fonctionné pour moi (la première ligne était nécessaire):

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

J'ai le même problème et mon Python est 2.7.11. Après avoir ajouté la deuxième ligne # -*- coding: utf-8 -*-en haut du fichier, il a résolu le problème.
hailong

2
La première ligne consiste à rendre le fichier py exécutable sur * nix. Ce n'est pas vraiment lié à cette question.
cmd

57

Ajoutez d'abord la # -*- coding: utf-8 -*-ligne au début du fichier, puis utilisez-la u'foo'pour toutes vos données Unicode non ASCII:

def NewFunction():
    return u'£'

ou utilisez la magie disponible depuis Python 2.6 pour le rendre automatique:

from __future__ import unicode_literals

12
Si vous l'avez, # -*- coding: utf-8 -*-vous n'avez pas besoin de préfixer vos chaînes unicode avecu
Daniel Lee

@plaes qu'en est-il si c'est sur une variable? exemple en lisant un fichier? Je ne peux pas utiliser uVariable, comment je fais?
Skizo-ozᴉʞS

1
@DanielLee Sauf que ce n'est pas vrai. # -*- coding: utf-8 -*-suivi par print 'błąd'affichera les ordures, pendant le print u'błąd'travail.
Przemek D

@DanielLee Ce que Przemek D a dit. Placer des littéraux UTF-8 dans votre code source comme celui-ci n'est généralement pas une bonne idée, et peut conduire à un comportement indésirable, en particulier dans Python 2. Si les littéraux ne sont pas de l'ASCII 7 bits pur, ils devraient être de l'Unicode réel, pas UTF-8, donc en Python 2 vous devez mettre le upréfixe sur de tels littéraux. En Python 3, les chaînes simples sont de toute façon Unicode, mais le upréfixe est autorisé dans les versions récentes de Python 3 pour faciliter l'écriture de code qui se comporte correctement en Python 2 et 3.
PM 2Ring

12

Le message d'erreur vous indique exactement ce qui ne va pas. L'interpréteur Python doit connaître le codage du caractère non ASCII.

Si vous souhaitez retourner U + 00A3, vous pouvez dire

return u'\u00a3'

qui représente ce caractère en ASCII pur au moyen d'une séquence d'échappement Unicode. Si vous souhaitez renvoyer une chaîne d'octets contenant l'octet littéral 0xA3, c'est

return b'\xa3'

(où en Python 2 le best implicite; mais explicite vaut mieux qu'implicite).

Le PEP lié dans le message d'erreur vous indique exactement comment dire à Python "ce fichier n'est pas pur ASCII; voici l'encodage que j'utilise". Si le codage est UTF-8, ce serait

# coding=utf-8

ou compatible Emacs

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

Si vous ne savez pas quel encodage votre éditeur utilise pour enregistrer ce fichier, examinez-le avec quelque chose comme un éditeur hexadécimal et quelques recherches sur Google. Le débordement de pileLa balise a une page d'informations sur la balise avec plus d'informations et quelques conseils de dépannage.

En tant de mots, en dehors de la plage ASCII 7 bits (0x00-0x7F), Python ne peut pas et ne doit pas deviner quelle chaîne représente une séquence d'octets. https://tripleee.github.io/8bit#a3 montre 21 interprétations possibles pour l'octet 0xA3 et c'est seulement à partir des encodages 8 bits hérités; mais il pourrait également très bien être le premier octet d'un codage multi-octets. Mais en fait, je suppose que vous utilisez réellement Latin-1, vous devriez donc avoir

# coding: latin-1

comme première ou deuxième ligne de votre fichier source. Quoi qu'il en soit, sans savoir quel caractère l'octet est censé représenter, un humain ne pourrait pas non plus le deviner.

Une mise en garde: coding: latin-1supprimera définitivement le message d'erreur (car il n'y a pas de séquences d'octets qui ne sont pas techniquement autorisées dans cet encodage), mais pourrait produire complètement le mauvais résultat lorsque le code est interprété si l'encodage réel est autre chose. Vous devez vraiment connaître l'encodage du fichier en toute certitude lorsque vous déclarez l'encodage.


Ceci est une adaptation d'une de mes réponses précédentes à une question en double: stackoverflow.com/a/50829958/874188
tripleee

Python 3 utilise par défaut UTF-8 pour les fichiers source, et vous devriez probablement utiliser UTF-8 pour tout de nos jours de toute façon. utf8everywhere.org
tripleee

8

L'ajout des deux lignes suivantes dans le script a résolu le problème pour moi.

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

J'espère que ça aide !


2

Vous essayez probablement d'exécuter un fichier Python 3 avec l'interpréteur Python 2. Actuellement (à partir de 2019), la pythoncommande utilise par défaut Python 2 lorsque les deux versions sont installées, sur Windows et la plupart des distributions Linux.

Mais si vous travaillez en effet sur un script Python 2, une solution non encore mentionnée sur cette page consiste à réenregistrer le fichier au format UTF-8 + BOM, ce qui ajoutera trois octets spéciaux au début du fichier, ils le feront informer explicitement l'interpréteur Python (et votre éditeur de texte) du codage du fichier.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.