Ngoài nhận được decode
và encode
ngược lại, tôi nghĩ một phần câu trả lời ở đây thực sự là không sử dụng mã hóa ascii
. Nó có thể không phải là những gì bạn muốn.
Để bắt đầu, hãy nghĩ đến str
giống như bạn sẽ là một tệp văn bản thuần túy. Nó chỉ là một loạt các byte mà không có mã hóa thực sự gắn liền với nó. Làm thế nào nó được giải thích là đến bất cứ phần nào của mã được đọc nó. Nếu bạn không biết đoạn văn này nói về điều gì, hãy đọc số The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets của Joel ngay bây giờ trước khi bạn tiếp tục.
Đương nhiên, chúng ta đều nhận thức được sự lộn xộn đã tạo ra. Câu trả lời là, ít nhất là trong bộ nhớ, có một mã hóa tiêu chuẩn cho tất cả các chuỗi. Đó là nơi mà unicode
xuất hiện. Tôi đang gặp khó khăn khi theo dõi chính xác những gì mã hóa Python sử dụng nội bộ chắc chắn, nhưng nó không thực sự quan trọng chỉ cho việc này. Vấn đề là bạn biết đó là một chuỗi các byte được diễn giải theo một cách nhất định. Vì vậy, bạn chỉ cần suy nghĩ về các nhân vật, chứ không phải các byte.
Vấn đề là trong thực tế, bạn chạy vào cả hai.Một số thư viện cung cấp cho bạn str
và một số thư viện mong đợi một số str
. Chắc chắn điều đó có ý nghĩa bất cứ khi nào bạn đang phát trực tuyến một chuỗi các byte (chẳng hạn như đến hoặc từ đĩa hoặc qua yêu cầu web). Vì vậy, bạn cần để có thể dịch qua lại.
Nhập codecs
: đó là thư viện bản dịch giữa hai loại dữ liệu này. Bạn sử dụng encode
để tạo một chuỗi các byte (str
) từ một chuỗi văn bản (unicode
) và bạn sử dụng decode
để nhận chuỗi văn bản (unicode
) từ một chuỗi byte (str
).
Ví dụ:
>>> s = "I look like a string, but I'm actually a sequence of bytes. \xe2\x9d\xa4"
>>> codecs.decode(s, 'utf-8')
u"I look like a string, but I'm actually a sequence of bytes. \u2764"
gì xảy ra ở đây? Tôi đã cho Python một chuỗi các byte, và sau đó tôi đã nói với nó, "Hãy cho tôi phiên bản unicode
về điều này, cho rằng chuỗi byte này là trong 'utf-8'
." Nó đã làm như tôi đã hỏi, và những byte (a heart character) bây giờ được xử lý như một toàn thể, đại diện bởi codepoint Unicode của họ.
Hãy đi theo con đường khác xung quanh:
>>> u = u"I'm a string! Really! \u2764"
>>> codecs.encode(u, 'utf-8')
"I'm a string! Really! \xe2\x9d\xa4"
Tôi đưa cho Python một chuỗi Unicode, và tôi hỏi nó để dịch các chuỗi thành một chuỗi các byte bằng cách sử dụng mã hóa 'utf-8'
. Vì vậy, nó đã làm, và bây giờ trái tim chỉ là một bó của byte nó không thể in như ASCII; vì vậy nó cho tôi thấy hệ thập lục phân thay thế.
Chúng ta có thể làm việc với mã hóa khác cũng vậy, tất nhiên:
>>> s = "I have a section \xa7"
>>> codecs.decode(s, 'latin1')
u'I have a section \xa7'
>>> codecs.decode(s, 'latin1')[-1] == u'\u00A7'
True
>>> u = u"I have a section \u00a7"
>>> u
u'I have a section \xa7'
>>> codecs.encode(u, 'latin1')
'I have a section \xa7'
(. '\xa7'
là section character, trong cả hai Unicode và Latin-1)
Vì vậy, câu hỏi của bạn, trước tiên bạn cần phải tìm hiểu xem mã hóa số str
của bạn là gì.
Nó đến từ tệp? Từ yêu cầu web? Từ cơ sở dữ liệu của bạn? Sau đó, nguồn xác định mã hóa. Tìm hiểu mã hóa của nguồn và sử dụng nó để dịch nó thành một unicode
.
s = [get from external source]
u = codecs.decode(s, 'utf-8') # Replace utf-8 with the actual input encoding
Hoặc có thể bạn đang cố viết nó ở đâu đó. Những gì mã hóa nào các điểm đến mong đợi? Sử dụng nó để dịch nó thành một str
. UTF-8 là một lựa chọn tốt cho các tài liệu văn bản thuần túy; hầu hết mọi thứ có thể đọc nó.
u = u'My string'
s = codecs.encode(u, 'utf-8') # Replace utf-8 with the actual output encoding
[Write s out somewhere]
Bạn chỉ cần dịch qua lại trong bộ nhớ cho khả năng tương tác hay gì đó? Sau đó, chỉ cần chọn một mã hóa và gắn bó với nó; 'utf-8'
có lẽ là lựa chọn tốt nhất cho điều đó:
u = u'My string'
s = codecs.encode(u, 'utf-8')
newu = codecs.decode(s, 'utf-8')
Trong lập trình hiện đại, bạn có lẽ không bao giờ muốn sử dụng mã hóa 'ascii'
cho bất kỳ này. Đó là một tập hợp con rất nhỏ của tất cả các ký tự có thể, và không có hệ thống nào tôi biết sử dụng nó theo mặc định hoặc bất cứ thứ gì.
Python 3 làm hết sức mình để làm cho điều này vô cùng rõ ràng hơn chỉ đơn giản bằng cách thay đổi tên.Trong Python 3, str
được thay thế bằng bytes
và unicode
được thay thế bằng str
.
Giá trị của 'chuỗi' là gì? Loại đó là gì? –
Nó không có ý nghĩa để giải mã một đối tượng Unicode vì nó đã ở dạng giải mã. Khi bạn gọi unicode_object.decode(), Python giả sử bạn muốn giải mã một chuỗi byte thành Unicode thay thế. Đầu tiên nó cố gắng mã hóa đối tượng Unicode dưới dạng chuỗi byte bằng cách sử dụng mã hóa mặc định của hệ thống - đó là lỗi thực sự bạn đang thấy. – kumar303