SyntaxError: не-ASCII символ '\ xa3' в файле, когда функция возвращает '£'


284

Скажем, у меня есть функция:

def NewFunction():
    return '£'

Я хочу напечатать кое-что со знаком решетки перед ним, и это выдает ошибку, когда я пытаюсь запустить эту программу, это сообщение об ошибке отображается:

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

Может кто-нибудь сообщить мне, как я могу включить знак фунта в мою функцию возврата? Я в основном использую это в классе, и это в той '__str__'части, в которую включен знак фунта.


43
Вы даже читали PEP, на который ссылались? Он описывает, в чем проблема и как ее исправить.
murgatroid99

2
«Может кто-нибудь сообщить мне, как я могу включить знак фунта в мою функцию возврата». Что ж, в сообщении об ошибке говорится «см. Python.org/peps/pep-0263.html »; возможно, вам стоит начать там?
Карл Кнехтель

5
@ murgatroid99 Вот что вы, и в то время, когда я набираю эти 27, отсутствуют: Да, конечно, я прочитаю PEP. Уровень сложности: я получил это, пытаясь запустить / bin / sh против контейнера докера. Я не открыто пытаюсь запустить Python. Таким образом, все, что PEP собирается сказать мне, это как исправить код Python, который я не пытался запустить и не писал. Я надеялся получить больше контекста от StackOverflow, вместо этого получил самодовольство. :( Дальнейший поиск
Марк Аллен

@MarkAllen - в вашем связанном ответе сообщение об ошибке указывает на то, что python пытается интерпретировать «/ bin / bash» - это по общему признанию что-то простое, но в этом вопросе ничего не указывает на то, что оно связано с докером или контейнером, поэтому совет здесь, как вы обнаружили, это не относится к вашей проблеме - это не самодовольство, просто в вашей проблеме есть контекст, которого здесь нет.
танванш

@tanantish Я придерживаюсь того, что сказал. Я получил ошибку в вопросе. Вместо того, чтобы давать полезную информацию людям, с которыми встречались, «Вы даже читали PEP, с которым вы связаны?» и "Ну, в сообщении об ошибке написано, видите (бла), возможно, вы должны начать там?" <- Эти ответы не помогают. Я не уверен, почему у нас это обсуждение.
Марк Аллен

Ответы:


368

Я бы рекомендовал прочитать, что PEP выдает ошибка. Проблема в том, что ваш код пытается использовать кодировку ASCII, но символ фунта не является символом ASCII. Попробуйте использовать кодировку UTF-8. Вы можете начать с размещения # -*- coding: utf-8 -*-в верхней части вашего .py файла. Чтобы продвинуться дальше, вы также можете определять кодировки по строкам в вашем коде. Однако, если вы пытаетесь вставить литеральный знак в ваш код, вам потребуется кодировка, которая поддерживает его для всего файла.


306

Добавление следующих двух строк привело к тому, что мой скрипт .py работал (первая строка была необходима):

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

У меня та же проблема, и мой Python 2.7.11. После добавления второй строки # -*- coding: utf-8 -*-в начало файла, это решило проблему.
Хайлонг

2
Первая строка - сделать исполняемый файл py на * nix. Это на самом деле не связано с этим вопросом.
CMD

57

Сначала добавьте # -*- coding: utf-8 -*-строку в начало файла, а затем используйте u'foo'для всех ваших данных Unicode, не относящихся к ASCII:

def NewFunction():
    return u'£'

или используйте магию, доступную начиная с Python 2.6, чтобы сделать ее автоматической:

from __future__ import unicode_literals

12
Если у вас есть, # -*- coding: utf-8 -*-вам не нужно добавлять префиксы к юникодуu
Daniel Lee

@plaes как насчет, если это переменная? пример чтения файла? Я не могу использовать uVariable, как мне это сделать?
Skizo-ozᴉʞS

1
@DanielLee За исключением того, что это не так. # -*- coding: utf-8 -*-затем print 'błąd'будет выводить мусор, пока print u'błąd'работает.
Przemek D

@DanielLee Что сказал Przemek D. Встраивание литералов UTF-8 в ваш исходный код, как правило, не очень хорошая идея, и может привести к нежелательному поведению, особенно в Python 2. Если литералы не являются чистым 7-битным ASCII, они должны быть фактическим Unicode, а не UTF-8, поэтому в Python 2 вы должны поставить uпрефикс для таких литералов. В Python 3 простые строки в любом случае являются Unicode, но uпрефикс разрешен в последних версиях Python 3, чтобы немного упростить написание кода, который ведет себя корректно как в Python 2, так и в 3
PM 2Ring

12

Сообщение об ошибке говорит вам, что именно не так. Интерпретатор Python должен знать кодировку не-ASCII символа.

Если вы хотите вернуть U + 00A3, то вы можете сказать,

return u'\u00a3'

который представляет этот символ в чистом ASCII посредством escape-последовательности Unicode. Если вы хотите вернуть байтовую строку, содержащую буквенный байт 0xA3, это

return b'\xa3'

(где в Python 2 bнеявный; но явный лучше, чем неявный).

Связанный PEP в сообщении об ошибке объясняет , как именно сказать Python: «Этот файл не является чистым ASCII; вот кодировка, которую я использую». Если кодировка UTF-8, это будет

# coding=utf-8

или Emacs-совместимый

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

Если вы не знаете, какую кодировку использует ваш редактор для сохранения этого файла, изучите его с помощью чего-то вроде шестнадцатеричного редактора и некоторого поиска в Google. Переполнение стекаВ теге есть страница с информацией о тегах, содержащая дополнительную информацию и советы по устранению неполадок.

Иными словами, за пределами 7-битного диапазона ASCII (0x00-0x7F) Python не может и не должен угадывать, какую строку представляет последовательность байтов. https://tripleee.github.io/8bit#a3 показывает 21 возможную интерпретацию для байта 0xA3, и это только из устаревших 8-битных кодировок; но это также может быть первый байт многобайтовой кодировки. Но на самом деле, я предполагаю, что вы на самом деле используете Latin-1, так что вы должны иметь

# coding: latin-1

как первая или вторая строка вашего исходного файла. В любом случае, без знания того, какой символ должен представлять байт, человек также не сможет догадаться об этом.

Предостережение: coding: latin-1определенно удалит сообщение об ошибке (потому что нет никаких последовательностей байтов, которые технически не разрешены в этой кодировке), но может привести к совершенно неправильному результату, когда код интерпретируется, если фактическая кодировка является чем-то другим. Вы действительно должны знать кодировку файла с полной уверенностью, когда вы объявляете кодировку.


Это адаптация моего более раннего ответа на
двойной

В Python 3 по умолчанию используется UTF-8 для исходных файлов, и вам, вероятно, все равно следует использовать UTF-8 для всего в наши дни. utf8everywhere.org
tripleee

8

Добавление следующих двух строк в сценарий решило проблему для меня.

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

Надеюсь, поможет !


2

Вы, вероятно, пытаетесь запустить файл Python 3 с интерпретатором Python 2. В настоящее время (по состоянию на 2019 г.) pythonкоманда по умолчанию установлена ​​на Python 2, когда установлены обе версии, в Windows и большинстве дистрибутивов Linux.

Но если вы действительно работаете над сценарием Python 2, решение, которое еще не упомянуто на этой странице, состоит в том, чтобы сохранить файл в кодировке UTF-8 + BOM, который добавит три специальных байта в начало файла, они будут явно сообщите интерпретатору Python (и вашему текстовому редактору) о кодировке файла.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.