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 проти контейнера docker. Я не відверто намагаюся запустити Python. Отже, всі PEP збираються мені сказати, як виправити код python, який я не намагаюся запустити і не написав. Я сподівався на більше контексту від StackOverflow, натомість отримав самовдоволення. :( Подальший пошук виявив фактичну відповідь: stackoverflow.com/questions/38992850/… - зауважте, як PEP зробив рівно нуль, щоб допомогти.
Марк Аллен

@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'для всіх своїх даних, що не стосуються 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 Що сказав Пшемек Д. Введення літералів 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 за допомогою послідовності відходу Unicode. Якщо ви хочете повернути рядок байтів, що містить буквальний байт 0xA3, це

return b'\xa3'

(де в Python 2 значення bнеявне, але явне краще, ніж неявне).

Зв'язаний PEP у повідомленні про помилку вказує вам , як саме сказати Python "цей файл не є чистим ASCII; ось кодування, яке я використовую". Якщо кодування UTF-8, це було б

# coding=utf-8

або сумісні з Emacs

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

Якщо ви не знаєте, яке кодування ваш редактор використовує для збереження цього файлу, вивчіть його за допомогою чогось шестигранного редактора та якогось googling. Переповнення стекаТег має сторінку з інформацією про теги з додатковою інформацією та деякими порадами щодо усунення несправностей.

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

# coding: latin-1

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

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


Це адаптація більш раннього відповіді шахти до дубліката питання: stackoverflow.com/a/50829958/874188
tripleee

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.