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เพื่อดูรายละเอียด"; บางทีคุณควรเริ่มจากตรงนั้นเหรอ?
Karl Knechtel

5
@ murgatroid99 นี่คือสิ่งที่คุณและในขณะที่ฉันพิมพ์ 27 คนนี้หายไป: ใช่แน่นอนฉันจะอ่าน PEP ระดับความยาก: ฉันได้พยายามเรียกใช้ / bin / sh กับคอนเทนเนอร์นักเทียบท่า ฉันไม่ได้พยายามเรียกใช้ Python อย่างเปิดเผย ดังนั้น PEP ทั้งหมดจะบอกฉันว่าเป็นวิธีการแก้ไขรหัสหลามฉันไม่ได้พยายามที่จะทำงานและไม่ได้เขียน ฉันหวังว่าจะได้รับบริบทเพิ่มเติมจาก StackOverflow ให้ได้ความอัปยศแทน :( การค้นหาเพิ่มเติมทำให้เกิดคำตอบที่แท้จริง: stackoverflow.com/questions/38992850/… - สังเกตว่า PEP ทำหน้าที่เป็นศูนย์ช่วยเหลืออย่างไร
Mark Allen

@ MarkAllen - ในคำตอบที่เชื่อมโยงของคุณข้อความแสดงข้อผิดพลาดระบุว่า python พยายามตีความ "/ bin / bash" - เป็นที่ยอมรับว่าเป็นสิ่งที่มองข้ามได้ง่าย แต่ไม่มีสิ่งใดในคำถามนี้ที่บ่งบอกว่ามันเกี่ยวข้องกับนักเทียบท่าหรือคอนเทนเนอร์ ที่นี่ตามที่คุณพบไม่ได้ใช้กับปัญหาของคุณ - ไม่ใช่ความไม่สบายใจ แต่เป็นเพียงแค่ว่ามีบริบทในปัญหาของคุณที่ไม่ได้ปรากฏที่นี่
tanantish

@ Tanantish ฉันยืนตามสิ่งที่ฉันพูด ฉันพบข้อผิดพลาดในคำถาม แทนที่จะให้ข้อมูลที่เป็นประโยชน์กับผู้คนที่เคยพบนี้ "คุณเคยอ่าน PEP ที่คุณเชื่อมโยงด้วยหรือไม่" และ "ข้อความแสดงข้อผิดพลาดบอกว่าเห็น (blah) ก่อนอื่นคุณควรเริ่มที่นั่นไหม" <- คำตอบเหล่านั้นไม่เป็นประโยชน์ ฉันไม่แน่ใจว่าทำไมเราถึงมีการสนทนานี้
Mark Allen

คำตอบ:


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 -*-ไปที่ด้านบนของไฟล์มันจะแก้ไขปัญหาได้
hailong

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 -*-คุณไม่จำเป็นต้องนำหน้าสตริง Unicode ของคุณด้วย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 interpreter จำเป็นต้องรู้การเข้ารหัสของอักขระที่ไม่ใช่ 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 -*-

หากคุณไม่ทราบว่าการเข้ารหัสใดที่โปรแกรมแก้ไขของคุณใช้ในการบันทึกไฟล์นี้ให้ตรวจสอบด้วยโปรแกรมแก้ไข hex และ googling กองล้นแท็กมีหน้าข้อมูลแท็กพร้อมข้อมูลเพิ่มเติมและเคล็ดลับการแก้ปัญหา

มีหลายคำที่อยู่นอกเหนือจากช่วง ASCII 7 บิต (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 interpreter ปัจจุบัน (ราว 2019) pythonคำสั่งเริ่มต้นเป็น Python 2 เมื่อติดตั้งทั้งสองเวอร์ชันบน Windows และ Linux ส่วนใหญ่

แต่ในกรณีที่คุณกำลังทำงานกับสคริปต์ Python 2 วิธีที่ไม่ได้กล่าวถึงในหน้านี้คือการบันทึกไฟล์ในการเข้ารหัส UTF-8 + BOM ซึ่งจะเพิ่มสามไบต์พิเศษให้กับจุดเริ่มต้นของไฟล์ แจ้งล่าม Python (และตัวแก้ไขข้อความของคุณ) อย่างชัดเจนเกี่ยวกับการเข้ารหัสไฟล์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.