Sözdizimi Hatası: İşlev '£' döndürdüğünde dosyada ASCII olmayan '\ xa3' karakteri


284

Diyelim ki bir fonksiyonum var:

def NewFunction():
    return '£'

Önünde bir sayı işareti olan bazı şeyleri yazdırmak istiyorum ve bu programı çalıştırmaya çalıştığımda bir hata yazdırıyor, bu hata mesajı görüntülenir:

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

Birisi bana dönüş fonksiyonuma nasıl bir pound işareti ekleyebileceğimi bildirebilir mi? Temelde bir sınıfta kullanıyorum '__str__'ve pound işareti dahil kısmı içinde .


43
Bağlandığınız PEP'i bile okudunuz mu? Sorunun ne olduğunu ve nasıl düzeltileceğini açıklar.
murgatroid99

2
"Herkes bana dönüş fonksiyonuma nasıl bir pound işareti ekleyebileceğimi bildirebilir." Hata mesajı " ayrıntılar için bkz. Python.org/peps/pep-0263.html "; belki oradan başlamalısın?
Karl Knechtel

5
@ murgatroid99 İşte siz ve bu yazarken 27 başka eksik: Evet tabii ki PEP okuyacağım. Zorluk seviyesi: Bunu bir docker konteynerine karşı / bin / sh çalıştırmaya çalıştım. Açıkça Python'u çalıştırmaya çalışmıyorum. Yani tüm PEP bana söylemeye çalışacağım python kodunu nasıl düzeltmeye çalışacağım ve yazmadım. StackOverflow daha fazla bağlam umuyordum, yerine kaçak var. :( Daha fazla araştırma asıl cevabı verdi: stackoverflow.com/questions/38992850/… - PEP'in nasıl yardımcı olduğunu tam olarak sıfırladığını fark et
Mark Allen

@MarkAllen - bağlantılı cevabınızda, hata mesajı python'un "/ bin / bash" ı yorumlamaya çalıştığını gösterir - kuşkusuz gözden kaçırmak kolay bir şeydir, ancak bu sorudaki hiçbir şey bunun liman işçisiyle veya konteynerle ilgili olduğunu göstermez, bu nedenle tavsiye burada bulduğunuz gibi probleminiz için geçerli değil - bu kaçakçılık değil, sadece probleminizde bağlam var, burada mevcut değil.
tanantish

@tanantish Söylediklerimin yanındayım. Sorudaki hatayı aldım. İnsanlara bununla ilgili yararlı bilgiler vermek yerine, "Bağlandığınız PEP'i bile okudunuz mu?" ve "Peki hata mesajı bkz. (falan), belki oradan başlamalısın?" <- Bu yanıtlar yardımcı olmuyor. Neden bu tartışmayı yaptığımızdan emin değilim.
Mark Allen

Yanıtlar:


368

Hatanın size verdiği PEP'i okumanızı tavsiye ederim. Sorun, kodunuz ASCII kodlamasını kullanmaya çalışıyor, ancak pound sembolü bir ASCII karakteri değil. UTF-8 kodlamasını kullanmayı deneyin. # -*- coding: utf-8 -*-.Py dosyanızın en üstüne koyarak başlayabilirsiniz . Daha gelişmiş olmak için, kodunuzda bir dizeye göre dize bazında kodlamalar tanımlayabilirsiniz. Ancak, pound işaretini kelimenin tam anlamıyla kodunuza yerleştirmeye çalışıyorsanız, dosyanın tamamı için bunu destekleyen bir kodlamaya ihtiyacınız olacaktır.


306

Aşağıdaki iki satırı eklemek benim için .py betiğimin üst kısmında oturdu (ilk satır gerekliydi):

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

Aynı sorunu yaşadım ve Python'um 2.7.11. İkinci satırı # -*- coding: utf-8 -*-dosyanın üstüne ekledikten sonra sorunu çözdü.
Hailong

2
İlk satır, * nix üzerinde py dosyasını çalıştırılabilir yapmaktır. Gerçekten bu soru ile ilgili değil.
cmd

57

Öncelikle # -*- coding: utf-8 -*-satırı dosyanın başına ekleyin ve ardından u'foo'ASCII olmayan tüm unicode verileriniz için kullanın:

def NewFunction():
    return u'£'

veya otomatik hale getirmek için Python 2.6'dan beri mevcut olan sihri kullanın:

from __future__ import unicode_literals

12
Eğer varsa # -*- coding: utf-8 -*-, unicode dizelerinizi ön ek olarak kullanmanız gerekmezu
Daniel Lee

@plaes değişkene sahipse ne olur? dosya okuyarak örnek? UVariable'ı kullanamıyorum, nasıl yaparım?
Skizo-ozᴉʞS

1
@DanielLee Bu doğru değil. # -*- coding: utf-8 -*-daha sonra print 'błąd'çöp verirken print u'błąd'çalışır.
Przemek D

@DanielLee Przemek D söyledi. Kaynak kodunuza UTF-8 değişmezlerini koymak genellikle iyi bir fikir değildir ve özellikle Python 2'de istenmeyen davranışlara yol açabilir. Değişmez değerler 7 bitlik ASCII değilse, gerçek Unicode olmalıdır, UTF-8 değil, Python 2'de uöneki bu gibi değişmez değerlere koymalısınız . Python 3'te, düz dizeler yine de Unicode'dur, ancak uPython 3'ün son sürümlerinde önek, Python 2 ve 3'te doğru davranan kod yazmayı biraz daha kolaylaştırmak için izin verilir:
PM 2Ring

12

Hata mesajı neyin yanlış olduğunu size söyler. Python yorumlayıcısının ASCII olmayan karakterin kodlamasını bilmesi gerekir.

U + 00A3'e dönmek istiyorsanız şunu söyleyebilirsiniz:

return u'\u00a3'

Unicode kaçış dizisi ile saf ASCII'de bu karakteri temsil eder. 0xA3 değişmez baytını içeren bir bayt dizesi döndürmek istiyorsanız,

return b'\xa3'

(burada Python 2'de börtük; ancak örtük, örtükten daha iyidir).

Hata mesajındaki bağlantılı PEP, Python'a "bu dosyanın saf ASCII olmadığını; işte kullandığım kodlamayı" nasıl söyleyeceğini tam olarak söyler. Kodlama UTF-8 ise, bu

# coding=utf-8

veya Emacs uyumlu

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

Bu dosyayı kaydetmek için düzenleyicinizin hangi kodlamayı kullandığını bilmiyorsanız, onaltılı düzenleyici ve bazı googling gibi bir şeyle inceleyin. Yığın Taşmasıetiketi, daha fazla bilgi ve sorun giderme ipuçları içeren bir etiket bilgisi sayfasına sahiptir.

Pek çok deyişle, 7 bit ASCII aralığının dışında (0x00-0x7F), Python bir bayt dizisinin hangi dizeyi temsil ettiğini tahmin edemez ve tahmin etmemelidir. https://tripleee.github.io/8bit#a3 , bayt 0xA3 için 21 olası yorumu gösterir ve bu yalnızca eski 8 bit kodlamalardan elde edilir; ancak çok baytlı kodlamanın ilk baytı da çok iyi olabilir. Ama aslında, aslında Latin-1 kullandığınızı tahmin ediyorum, bu yüzden

# coding: latin-1

kaynak dosyanızın ilk veya ikinci satırı olarak. Her neyse, baytın hangi karakteri temsil etmesi gerektiği bilgisi olmadan, bir insan da bunu tahmin edemezdi.

Bir uyarı: coding: latin-1hata mesajını kesinlikle kaldıracaktır (çünkü bu kodlamada teknik olarak izin verilmeyen bayt dizileri yoktur), ancak gerçek kodlama başka bir şeyse kod yorumlandığında tamamen yanlış sonuç verebilir. Kodlamayı bildirirken dosyanın kodlamasını tam olarak bilmek zorundasınız.


Bu, daha önceki bir cevabımın yinelenen bir soruya
uyarlanmasıdır

Python 3, kaynak dosyalar için varsayılan olarak UTF-8'dir ve muhtemelen bu günlerde her şey için UTF-8 kullanmalısınız. utf8everywhere.org
üçlü

8

Betiğe aşağıdaki iki satırı eklemek sorunu benim için çözdü.

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

Umarım yardımcı olur !


2

Muhtemelen Python 3 dosyasını Python 2 yorumlayıcısıyla çalıştırmaya çalışıyorsunuz. Şu anda (2019 itibariyle), pythonher iki sürüm de yüklendiğinde, Windows ve çoğu Linux dağıtımında komut varsayılan olarak Python 2'dir.

Ancak gerçekten bir Python 2 komut dosyası üzerinde çalışıyorsanız, bu sayfada henüz belirtilmeyen bir çözüm, dosyanın başlangıcına üç özel bayt ekleyecek olan UTF-8 + BOM kodlamasında dosyayı yeniden kaydetmektir. Python yorumlayıcısını (ve metin düzenleyicinizi) dosya kodlaması hakkında açıkça bilgilendirin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.