Cú pháp: Ký tự không phải ASCII '\ xa3' trong tệp khi hàm trả về '£'


284

Nói rằng tôi có một chức năng:

def NewFunction():
    return '£'

Tôi muốn in một số nội dung có dấu thăng phía trước và nó in lỗi khi tôi cố chạy chương trình này, thông báo lỗi này được hiển thị:

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

Bất cứ ai có thể cho tôi biết làm thế nào tôi có thể bao gồm một dấu thăng trong chức năng trở lại của tôi? Về cơ bản, tôi đang sử dụng nó trong một lớp và nó nằm trong '__str__'phần có ký hiệu bảng Anh.


43
Bạn thậm chí đã đọc PEP mà bạn liên kết đến? Nó mô tả vấn đề là gì và cách khắc phục.
murgatroid99

2
"Bất cứ ai có thể thông báo cho tôi làm thế nào tôi có thể bao gồm một dấu thăng trong chức năng trở lại của tôi." Chà, thông báo lỗi cho biết "xem python.org/peps/pep-0263.html để biết chi tiết"; có lẽ bạn nên bắt đầu từ đó?
Karl Knechtel

5
@ murgatroid99 Đây là những gì bạn và tại thời điểm tôi gõ 27 cái khác đang thiếu: Tất nhiên tôi sẽ đọc PEP. Mức độ khó: Tôi nhận được điều này khi cố gắng chạy / bin / sh đối với một container docker. Tôi không cố tình chạy Python. Vì vậy, tất cả các PEP sẽ nói với tôi là làm thế nào để sửa mã python Tôi không cố chạy và không viết. Tôi đã hy vọng có thêm bối cảnh từ StackOverflow, thay vào đó là sự tự mãn. :( Hơn nữa tìm kiếm bật lên câu trả lời thực tế: stackoverflow.com/questions/38992850/... - thông báo như thế nào PEP đã làm chính xác không để được giúp đỡ.
Mark Allen

@MarkAllen - trong câu trả lời được liên kết của bạn, thông báo lỗi cho biết python đang cố gắng diễn giải "/ bin / bash" - đó là một điều dễ dàng bỏ qua, nhưng không có gì trong câu hỏi này chỉ ra rằng nó phải làm gì với docker hoặc container, vì vậy lời khuyên ở đây như bạn đã tìm thấy không áp dụng cho vấn đề của bạn - không phải là tự mãn, chỉ là có bối cảnh trong vấn đề của bạn, điều đó không có ở đây.
tanantish

@tanantish Tôi đứng trước những gì tôi nói. Tôi đã nhận được lỗi trong câu hỏi. Thay vì cung cấp thông tin hữu ích cho những người mà điều này đã được đáp ứng, "Bạn thậm chí đã đọc PEP mà bạn đã liên kết chưa?" và, "Vâng, thông báo lỗi nói rằng hãy xem (blah), bạn có nên bắt đầu từ đó không?" <- Những phản hồi đó không hữu ích. Tôi không chắc tại sao chúng ta có cuộc thảo luận này.
Mark Allen

Câu trả lời:


368

Tôi khuyên bạn nên đọc rằng PEP lỗi cung cấp cho bạn. Vấn đề là mã của bạn đang cố sử dụng mã hóa ASCII, nhưng ký hiệu bảng Anh không phải là ký tự ASCII. Hãy thử sử dụng mã hóa UTF-8. Bạn có thể bắt đầu bằng cách đặt # -*- coding: utf-8 -*-ở đầu tệp .py của bạn. Để nâng cao hơn, bạn cũng có thể xác định mã hóa trên chuỗi theo cơ sở chuỗi trong mã của mình. Tuy nhiên, nếu bạn đang cố gắng đặt ký hiệu bảng chữ cái vào mã của mình, bạn sẽ cần một mã hóa hỗ trợ nó cho toàn bộ tệp.


306

Thêm hai dòng sau vào đầu tập lệnh .py của tôi làm việc cho tôi (dòng đầu tiên là cần thiết):

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

Tôi đã có cùng một vấn đề và Python của tôi là 2.7.11. Sau khi thêm dòng thứ hai # -*- coding: utf-8 -*-vào đầu tệp, nó đã giải quyết vấn đề.
hailong

2
Dòng đầu tiên là làm cho tệp py thực thi trên * nix. Nó không thực sự liên quan đến câu hỏi này.
cmd

57

Trước tiên, thêm # -*- coding: utf-8 -*-dòng vào đầu tệp và sau đó sử dụng u'foo'cho tất cả dữ liệu unicode không phải ASCII của bạn:

def NewFunction():
    return u'£'

hoặc sử dụng phép thuật có sẵn từ Python 2.6 để làm cho nó tự động:

from __future__ import unicode_literals

12
Nếu bạn có, # -*- coding: utf-8 -*-bạn không cần phải thêm tiền tố vào chuỗi unicode của mìnhu
Daniel Lee

@plaes thì sao nếu nó là một biến? ví dụ bằng cách đọc một tập tin? Tôi không thể sử dụng uVariable, làm thế nào để tôi làm điều đó?
Skizo-ozᴉʞS ngày

1
@DanielLee Ngoại trừ điều này là không đúng sự thật. # -*- coding: utf-8 -*-tiếp theo print 'błąd'sẽ xuất rác, trong khi print u'błąd'hoạt động.
Przemek D

@DanielLee Những gì Przemek D nói. Việc đưa các chữ UTF-8 vào mã nguồn của bạn như thế thường không phải là một ý tưởng hay và có thể dẫn đến hành vi không mong muốn, đặc biệt là trong Python 2. Nếu chữ không phải là ASCII 7 bit thuần túy thì chúng phải là Unicode thực tế, không phải là UTF-8, Vì vậy, trong Python 2, bạn nên đặt utiền tố vào các chữ đó. Trong Python 3, dù sao thì các chuỗi đơn giản là Unicode, nhưng utiền tố được cho phép trong các phiên bản gần đây của Python 3 để giúp viết mã dễ dàng hơn một chút, hoạt động chính xác trong cả Python 2 & 3.
PM 2Ring

12

Thông báo lỗi cho bạn biết chính xác những gì sai. Trình thông dịch Python cần biết mã hóa ký tự không phải ASCII.

Nếu bạn muốn trả về U + 00A3 thì bạn có thể nói

return u'\u00a3'

đại diện cho ký tự này trong ASCII thuần túy bằng chuỗi thoát Unicode. Nếu bạn muốn trả về một chuỗi byte chứa byte bằng 0xA3, thì đó là

return b'\xa3'

(trong Python 2 bthì ẩn; nhưng rõ ràng là tốt hơn ẩn).

PEP được liên kết trong thông báo lỗi hướng dẫn bạn chính xác cách nói với Python "tệp này không phải là ASCII thuần túy; đây là mã hóa tôi đang sử dụng". Nếu mã hóa là UTF-8, đó sẽ là

# coding=utf-8

hoặc tương thích Emacs

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

Nếu bạn không biết trình mã hóa nào mà trình soạn thảo của bạn sử dụng để lưu tệp này, hãy kiểm tra nó với một cái gì đó như trình soạn thảo hex và một số googling. Tràn ngăn xếpThẻ có trang thông tin thẻ với nhiều thông tin hơn và một số mẹo khắc phục sự cố.

Trong rất nhiều từ, ngoài phạm vi ASCII 7 bit (0x00-0x7F), Python không thể và không đoán được chuỗi chuỗi nào biểu thị chuỗi nào. https://tripleee.github.io/8bit#a3 hiển thị 21 cách hiểu có thể có cho byte 0xA3 và đó chỉ là từ mã hóa 8 bit cũ; nhưng nó cũng rất có thể là byte đầu tiên của mã hóa nhiều byte. Nhưng trên thực tế, tôi đoán bạn thực sự đang sử dụng Latin-1, vì vậy bạn nên có

# coding: latin-1

là dòng đầu tiên hoặc thứ hai của tệp nguồn của bạn. Dù sao, nếu không có kiến ​​thức về ký tự mà byte được cho là đại diện, một con người cũng sẽ không thể đoán được điều này.

Thông báo trước: coding: latin-1chắc chắn sẽ xóa thông báo lỗi (vì không có chuỗi byte nào không được phép về mặt kỹ thuật trong mã hóa này), nhưng có thể tạo ra kết quả hoàn toàn sai khi mã được diễn giải nếu mã hóa thực tế là thứ khác. Bạn thực sự phải biết mã hóa tệp với sự chắc chắn hoàn toàn khi bạn khai báo mã hóa.


Đây là bản phóng tác của câu trả lời trước đó của tôi cho một câu hỏi trùng lặp: stackoverflow.com/a/50829958/874188
tripleee

Python 3 mặc định là UTF-8 cho các tệp nguồn và có lẽ bạn nên sử dụng UTF-8 cho mọi thứ trong những ngày này. utf8everywhere.org
tripleee

8

Thêm hai dòng sau trong kịch bản đã giải quyết vấn đề cho tôi.

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

Hy vọng nó giúp !


2

Có lẽ bạn đang cố chạy tệp Python 3 với trình thông dịch Python 2. Hiện tại (kể từ năm 2019), pythonlệnh mặc định cho Python 2 khi cả hai phiên bản được cài đặt, trên Windows và hầu hết các bản phân phối Linux.

Nhưng trong trường hợp bạn thực sự đang làm việc với tập lệnh Python 2, một giải pháp chưa được đề cập trên trang này là để lưu lại tệp trong mã hóa UTF-8 + BOM, chúng sẽ thêm ba byte đặc biệt vào đầu tệp, chúng sẽ thông báo rõ ràng cho trình thông dịch Python (và trình soạn thảo văn bản của bạn) về mã hóa tệp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.