SyntaxError: caractere não ASCII '\ xa3' no arquivo quando a função retorna '£'


284

Digamos que eu tenho uma função:

def NewFunction():
    return '£'

Quero imprimir algumas coisas com um sinal de libra na frente e ele imprime um erro quando tento executar este programa, essa mensagem de erro é exibida:

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

Alguém pode me informar como posso incluir um sinal de libra na minha função de retorno? Basicamente, estou usando-o em uma classe e é na '__str__'parte que o sinal de libra está incluído.


43
Você já leu o PEP ao qual vinculou? Ele descreve qual é o problema e como corrigi-lo.
Murgatroid99

2
"Alguém pode me informar como posso incluir um sinal de libra na minha função de retorno." Bem, a mensagem de erro diz "consulte python.org/peps/pep-0263.html para obter detalhes"; talvez você devesse começar por aí?
Karl Knechtel 14/05

5
@ murgatroid99 Aqui está o que você e no momento em que digito esses 27 outros estão ausentes: Sim, é claro que vou ler o PEP. Nível de dificuldade: Eu tentei executar / bin / sh em um contêiner de docker. Não estou abertamente tentando executar o Python. Então, todo o PEP vai me dizer como corrigir o código python que não estou tentando executar e não escrevi. Eu estava esperando por mais contexto do StackOverflow, obtive a presunção. :( busca adicional apareceu a resposta real: stackoverflow.com/questions/38992850/... - Observe como o PEP fez exatamente zero a ajuda.
Mark Allen

@ MarkAllen - na sua resposta vinculada, a mensagem de erro indica que o python está tentando interpretar "/ bin / bash" - é algo fácil de ignorar, mas nada nesta pergunta indica que esteja relacionado ao docker ou a um contêiner, portanto, o conselho aqui, como você descobriu, não se aplica ao seu problema - não é presunção, é apenas que há um contexto no seu problema, que não está presente aqui.
tanantish

@ tanantish Eu mantenho o que disse. Eu recebi o erro na pergunta. Em vez de fornecer informações úteis para as pessoas com quem isso foi encontrado, "Você leu o PEP ao qual vinculou?" e "Bem, a mensagem de erro diz ver (blá), talvez você deva começar por aí?" <- Essas respostas não são úteis. Não sei por que estamos tendo essa discussão.
Mark Allen

Respostas:


368

Eu recomendo ler esse PEP que o erro fornece. O problema é que seu código está tentando usar a codificação ASCII, mas o símbolo da libra não é um caractere ASCII. Tente usar a codificação UTF-8. Você pode começar colocando # -*- coding: utf-8 -*-no topo do seu arquivo .py. Para ficar mais avançado, você também pode definir codificações em uma string por string no seu código. No entanto, se você estiver tentando inserir literalmente o sinal de libra no seu código, precisará de uma codificação que o suporte a todo o arquivo.


306

A adição das duas linhas a seguir estava no topo do meu script .py funcionou para mim (a primeira linha era necessária):

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

Eu tenho o mesmo problema e meu Python é 2.7.11. Depois de adicionar a segunda linha # -*- coding: utf-8 -*-na parte superior do arquivo, ele resolveu o problema.
Hailong

2
A primeira linha é tornar o arquivo py executável em * nix. Não está realmente relacionado a esta questão.
Cmd

57

Primeiro adicione a # -*- coding: utf-8 -*-linha ao início do arquivo e use u'foo'para todos os seus dados unicode não ASCII:

def NewFunction():
    return u'£'

ou use a mágica disponível desde o Python 2.6 para torná-lo automático:

from __future__ import unicode_literals

12
Se você tem # -*- coding: utf-8 -*-, você não precisa prefixar seus strings unicode comu
Daniel Lee

@plaes e se estiver em uma variável? exemplo lendo um arquivo? Não consigo usar uVariable, como faço?
precisa saber é o seguinte

1
@DanielLee Exceto que isso não é verdade. # -*- coding: utf-8 -*-seguido por print 'błąd'produzirá lixo, enquanto print u'błąd'trabalha.
Przemek D

@DanielLee O que Przemek D disse. Colocar literais UTF-8 no código-fonte dessa maneira geralmente não é uma boa ideia e pode levar a comportamentos indesejados, especialmente no Python 2. Se os literais não forem ASCII puros de 7 bits, eles devem ser Unicode reais, não UTF-8, portanto, no Python 2, você deve colocar o uprefixo em tais literais. De qualquer forma, no Python 3, as strings simples são Unicode, mas o uprefixo é permitido nas versões recentes do Python 3 para tornar um pouco mais fácil escrever código que se comporte corretamente no Python 2 e 3.
PM 2Ring

12

A mensagem de erro informa exatamente o que está errado. O intérprete Python precisa conhecer a codificação do caractere não ASCII.

Se você deseja retornar U + 00A3 , pode dizer

return u'\u00a3'

que representa esse caractere em ASCII puro por meio de uma sequência de escape Unicode. Se você deseja retornar uma sequência de bytes contendo o byte literal 0xA3, isso é

return b'\xa3'

(onde no Python 2 bestá implícito; mas explícito é melhor que implícito).

O PEP vinculado na mensagem de erro instrui exatamente como informar ao Python "este arquivo não é puro ASCII; aqui está a codificação que estou usando". Se a codificação for UTF-8, isso seria

# coding=utf-8

ou compatível com o Emacs

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

Se você não souber qual codificação seu editor usa para salvar esse arquivo, examine-o com algo como um editor hexadecimal e um pouco de pesquisa no Google. O estouro de pilhatag tem uma página de informações da tag com mais informações e algumas dicas para solução de problemas.

Em muitas palavras, fora do intervalo ASCII de 7 bits (0x00-0x7F), o Python não pode e não deve adivinhar qual sequência de bytes uma sequência de bytes representa. https://tripleee.github.io/8bit#a3 mostra 21 interpretações possíveis para o byte 0xA3 e isso é apenas das codificações herdadas de 8 bits; mas também poderia muito bem ser o primeiro byte de uma codificação de vários bytes. Mas, na verdade, eu acho que você está realmente usando o Latin-1, então você deveria ter

# coding: latin-1

como a primeira ou a segunda linha do seu arquivo de origem. De qualquer forma, sem o conhecimento de qual caractere o byte deve representar, um humano também não seria capaz de adivinhar.

Uma ressalva: coding: latin-1definitivamente removerá a mensagem de erro (porque não há seqüências de bytes que não são tecnicamente permitidas nessa codificação), mas pode produzir completamente o resultado errado quando o código for interpretado se a codificação real for outra coisa. Você realmente precisa conhecer a codificação do arquivo com total certeza ao declarar a codificação.


Esta é uma adaptação de uma resposta anterior da mina para uma pergunta duplicado: stackoverflow.com/a/50829958/874188
tripleee

O padrão do Python 3 é o UTF-8 para arquivos de origem, e você provavelmente deve estar usando o UTF-8 para tudo hoje em dia. utf8everywhere.org
tripleee 29/06

8

A adição das duas linhas a seguir no script resolveu o problema para mim.

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

Espero que ajude !


2

Você provavelmente está tentando executar o arquivo Python 3 com o interpretador Python 2. Atualmente (a partir de 2019), o pythoncomando padrão é Python 2 quando as duas versões estão instaladas, no Windows e na maioria das distribuições Linux.

Porém, caso você esteja realmente trabalhando em um script Python 2, uma solução ainda não mencionada nesta página é salvar novamente o arquivo na codificação UTF-8 + BOM, que adicionará três bytes especiais ao início do arquivo. informe explicitamente o intérprete Python (e seu editor de texto) sobre a codificação do arquivo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.