SyntaxError: Nicht-ASCII-Zeichen '\ xa3' in der Datei, wenn die Funktion '£' zurückgibt.


284

Angenommen, ich habe eine Funktion:

def NewFunction():
    return '£'

Ich möchte einige Dinge mit einem Nummernzeichen davor drucken und es wird ein Fehler ausgegeben, wenn ich versuche, dieses Programm auszuführen. Diese Fehlermeldung wird angezeigt:

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

Kann mir jemand mitteilen, wie ich ein Nummernzeichen in meine Rückgabefunktion aufnehmen kann? Ich benutze es im Grunde genommen in einer Klasse und es ist innerhalb des '__str__'Teils, in dem das Pfundzeichen enthalten ist.


43
Hast du überhaupt den PEP gelesen, mit dem du verlinkt hast? Es beschreibt, was das Problem ist und wie es behoben werden kann.
Murgatroid99

2
"Kann mir jemand mitteilen, wie ich ein Pfundzeichen in meine Rückgabefunktion aufnehmen kann?" Nun, die Fehlermeldung lautet "siehe python.org/peps/pep-0263.html für Details"; Vielleicht solltest du dort anfangen?
Karl Knechtel

5
@ murgatroid99 Hier ist, was Sie und zu dem Zeitpunkt, an dem ich diese 27 tippe, vermissen: Ja, natürlich werde ich das PEP lesen. Schwierigkeitsgrad: Ich habe versucht, / bin / sh gegen einen Docker-Container auszuführen. Ich versuche nicht offen, Python auszuführen. Das PEP wird mir also nur sagen, wie man den Python-Code repariert, den ich nicht ausführen und nicht geschrieben habe. Ich hatte auf mehr Kontext von StackOverflow gehofft und stattdessen Selbstgefälligkeit bekommen. :( Weitere Suche ergab die eigentliche Antwort: stackoverflow.com/questions/38992850/… - Beachten Sie , wie der PEP genau Null tat, um zu helfen.
Mark Allen

@MarkAllen - In Ihrer verknüpften Antwort zeigt die Fehlermeldung an, dass Python versucht, "/ bin / bash" zu interpretieren. Es ist zwar leicht zu übersehen, aber nichts in dieser Frage weist darauf hin, dass es mit Docker oder einem Container zu tun hat Wie Sie festgestellt haben, trifft dies nicht auf Ihr Problem zu - es ist keine Selbstgefälligkeit, es ist nur so, dass Ihr Problem einen Kontext enthält, der hier nicht vorhanden ist.
Tanantish

@tanantish Ich stehe zu dem, was ich gesagt habe. Ich habe den Fehler in der Frage. Anstatt nützliche Informationen zu geben, wurde dies getroffen: "Haben Sie überhaupt den PEP gelesen, mit dem Sie verlinkt haben?" und: "Nun, die Fehlermeldung lautet sehen (bla), sollten Sie vielleicht dort anfangen?" <- Diese Antworten sind nicht hilfreich. Ich bin mir nicht sicher, warum wir diese Diskussion führen.
Mark Allen

Antworten:


368

Ich würde empfehlen, diesen PEP zu lesen, den der Fehler Ihnen gibt. Das Problem ist, dass Ihr Code versucht, die ASCII-Codierung zu verwenden, das Pfund-Symbol jedoch kein ASCII-Zeichen ist. Versuchen Sie es mit UTF-8-Codierung. Sie können beginnen, indem Sie # -*- coding: utf-8 -*-oben in Ihre .py-Datei einfügen. Um weiter zu kommen, können Sie in Ihrem Code auch Codierungen auf Zeichenfolgenbasis definieren. Wenn Sie jedoch versuchen, das Nummernzeichen-Literal in Ihren Code einzufügen, benötigen Sie eine Codierung, die es für die gesamte Datei unterstützt.


306

Das Hinzufügen der folgenden zwei Zeilen oben in meinem .py-Skript funktionierte für mich (die erste Zeile war erforderlich):

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

Ich habe das gleiche Problem und mein Python ist 2.7.11. Nachdem die zweite Zeile # -*- coding: utf-8 -*-oben in die Datei eingefügt wurde, wurde das Problem behoben.
Hagel am

2
Die erste Zeile besteht darin, die py-Datei auf * nix ausführbar zu machen. Es hat nicht wirklich mit dieser Frage zu tun.
cmd

57

Fügen Sie zuerst die # -*- coding: utf-8 -*-Zeile am Anfang der Datei hinzu und verwenden Sie sie dann u'foo'für alle Ihre Nicht-ASCII-Unicode-Daten:

def NewFunction():
    return u'£'

oder verwenden Sie die seit Python 2.6 verfügbare Magie, um es automatisch zu machen:

from __future__ import unicode_literals

12
Wenn Sie haben, müssen # -*- coding: utf-8 -*-Sie Ihren Unicode-Zeichenfolgen nicht mitu
Daniel Lee

@plaes was ist, wenn es auf einer Variablen ist? Beispiel durch Lesen einer Datei? Ich kann uVariable nicht verwenden, wie mache ich das?
Skizo-ozᴉʞS

1
@ DanielLee Außer das ist nicht wahr. # -*- coding: utf-8 -*-gefolgt von print 'błąd'wird Müll ausgeben, während print u'błąd'funktioniert.
Przemek D

@ DanielLee Was Przemek D gesagt hat. Das Einfügen von UTF-8-Literalen in Ihren Quellcode ist im Allgemeinen keine gute Idee und kann zu unerwünschtem Verhalten führen, insbesondere in Python 2. Wenn Literale kein reines 7-Bit-ASCII sind, sollten sie tatsächlich Unicode sein, nicht UTF-8. In Python 2 sollten Sie usolchen Literalen das Präfix hinzufügen. In Python 3 sind einfache Zeichenfolgen ohnehin Unicode, aber das uPräfix ist in neueren Versionen von Python 3 zulässig, um das Schreiben von Code zu vereinfachen, der sich in Python 2 und 3 korrekt verhält.
PM 2Ring

12

Die Fehlermeldung sagt Ihnen genau, was falsch ist. Der Python-Interpreter muss die Codierung des Nicht-ASCII-Zeichens kennen.

Wenn Sie U + 00A3 zurückgeben möchten, können Sie sagen

return u'\u00a3'

Dies repräsentiert dieses Zeichen in reinem ASCII über eine Unicode-Escape-Sequenz. Wenn Sie eine Bytezeichenfolge zurückgeben möchten, die das Literalbyte 0xA3 enthält, ist dies der Fall

return b'\xa3'

(wo in Python 2 das bimplizit ist; aber explizit ist besser als implizit).

Das verknüpfte PEP in der Fehlermeldung weist Sie genau an, wie Sie Python mitteilen sollen, dass es sich bei dieser Datei nicht um reines ASCII handelt. Hier ist die von mir verwendete Codierung. Wenn die Codierung UTF-8 ist, wäre das

# coding=utf-8

oder die Emacs-kompatiblen

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

Wenn Sie nicht wissen, welche Codierung Ihr Editor zum Speichern dieser Datei verwendet, überprüfen Sie sie mit einem Hex-Editor und etwas Googeln. Der StapelüberlaufDas Tag verfügt über eine Tag-Infoseite mit weiteren Informationen und einigen Tipps zur Fehlerbehebung.

In so vielen Worten kann und darf Python außerhalb des 7-Bit-ASCII-Bereichs (0x00-0x7F) nicht erraten, welche Zeichenfolge eine Folge von Bytes darstellt. https://tripleee.github.io/8bit#a3 zeigt 21 mögliche Interpretationen für das Byte 0xA3 und das ist nur aus den alten 8-Bit-Codierungen; Es könnte aber auch das erste Byte einer Mehrbyte-Codierung sein. Aber in der Tat würde ich vermuten, dass Sie tatsächlich Latin-1 verwenden, also sollten Sie haben

# coding: latin-1

als erste oder zweite Zeile Ihrer Quelldatei. Ohne zu wissen, welchen Charakter das Byte darstellen soll, könnte ein Mensch dies auch nicht erraten.

Eine Einschränkung: coding: latin-1Entfernt definitiv die Fehlermeldung (da es keine Byte-Sequenzen gibt, die in dieser Codierung technisch nicht zulässig sind), führt jedoch möglicherweise zu einem völlig falschen Ergebnis, wenn der Code interpretiert wird, wenn die tatsächliche Codierung etwas anderes ist. Sie müssen die Codierung der Datei wirklich mit absoluter Sicherheit kennen, wenn Sie die Codierung deklarieren.


Dies ist eine Anpassung einer früheren Antwort von mir an eine doppelte Frage: stackoverflow.com/a/50829958/874188
Tripleee

Python 3 verwendet standardmäßig UTF-8 für Quelldateien, und Sie sollten UTF-8 heutzutage wahrscheinlich sowieso für alles verwenden. utf8everywhere.org
Tripleee

8

Das Hinzufügen der folgenden zwei Zeilen im Skript löste das Problem für mich.

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

Ich hoffe es hilft !


2

Sie versuchen wahrscheinlich, eine Python 3-Datei mit einem Python 2-Interpreter auszuführen. Derzeit (Stand 2019) ist der pythonBefehl standardmäßig Python 2, wenn beide Versionen unter Windows und den meisten Linux-Distributionen installiert sind.

Wenn Sie jedoch tatsächlich an einem Python 2-Skript arbeiten, besteht eine auf dieser Seite noch nicht erwähnte Lösung darin, die Datei in UTF-8 + -BOM-Codierung erneut zu speichern, wobei dem Anfang der Datei drei spezielle Bytes hinzugefügt werden Informieren Sie den Python-Interpreter (und Ihren Texteditor) explizit über die Dateicodierung.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.