LƯU Ý: điều này được viết cho Python 2.x. Không chắc chắn nếu áp dụng cho 3.x.
Việc bạn sử dụng str
cho dữ liệu nhị phân thô trong bộ nhớ là chính xác.
[Nếu bạn đang sử dụng Python 2.6+, thậm chí tốt hơn nên sử dụng bytes
trong 2.6+ chỉ là bí danh str
nhưng thể hiện ý định của bạn tốt hơn và sẽ giúp nếu một ngày bạn chuyển mã sang Python 3.]
Như những lưu ý khác, việc ghi dữ liệu nhị phân qua codec là lạ. Mã ghi là có các mã số unicode và kết quả đầu ra byte vào tệp. Bạn đang cố gắng làm ngược lại, do đó sự nhầm lẫn của chúng tôi về ý định của bạn ...
[Và chẩn đoán lỗi của bạn có vẻ chính xác: vì codec mong đợi unicode, Python đang giải mã đường của bạn thành unicode với mã hóa mặc định của hệ thống , cuộn cảm.]
Bạn muốn xem gì trong tệp đầu ra?
Nếu tập tin nên chứa dữ liệu nhị phân như nó vốn có:
Sau đó, bạn không phải gửi nó qua một codec; bạn phải viết nó trực tiếp vào tệp.Một codec mã hóa mọi thứ và chỉ có thể phát ra mã hóa hợp lệ của unicode (trong trường hợp của bạn, hợp lệ UTF-8). Không có đầu vào nào bạn có thể cho nó để làm cho nó phát ra tùy ý chuỗi byte!
- Nếu bạn cần một hỗn hợp dữ liệu nhị phân UTF-8 và thô, bạn nên mở file trực tiếp, và intermix viết của
some_data
với some_text.encode('utf8')
...
Lưu ý tuy nhiên đó trộn UTF-8 với dữ liệu tùy ý thô là rất thiết kế kém, bởi vì các tệp như vậy rất bất tiện để xử lý với! Các công cụ hiểu unicode sẽ bị nghẹt thở trên dữ liệu nhị phân , khiến bạn không thuận tiện để xem ngay cả (hãy để một mình sửa đổi) tệp.
Nếu bạn muốn có một đại diện thân thiện của byte tùy ý trong unicode:
đèo data.encode('base64')
đến codec. Base64 chỉ tạo ra ascii sạch (chữ cái, số và dấu chấm câu nhỏ) để có thể nhúng rõ ràng vào bất cứ thứ gì, nó rõ ràng trông giống như dữ liệu nhị phân và nhỏ gọn hợp lý (trên 33% trên đầu).
P.S. bạn có thể lưu ý rằng data.encode('base64')
là lạ.
.encode()
là nghĩa vụ phải chăm unicode nhưng tôi cho nó một chuỗi ?! Python có một số codec giả để chuyển đổi str-> str như 'base64' và 'zlib'.
.encode()
luôn trả về một đường nhưng bạn sẽ chuyển nó vào codec mong đợi unicode ?! Trong trường hợp này nó sẽ chỉ chứa sạch ascii, vì vậy nó không quan trọng. Bạn có thể viết rõ ràng data.encode('base64').encode('utf8')
nếu điều đó làm cho bạn cảm thấy tốt hơn .
Nếu bạn cần một 1: lập bản đồ 1 từ byte tùy ý để Unicode:
đèo data.decode('latin1')
đến codec. latin1
bản đồ byte 0-255 để unicode ký tự 0-255, đó là kinda thanh lịch.
Codec sẽ mã hóa các ký tự của bạn - 128-255 là được mã hóa là 2 hoặc 3 byte trong UTF-8 (đáng ngạc nhiên, chi phí trung bình là 50%, nhiều hơn base64!). Điều này khá giết "sang trọng" của việc lập bản đồ 1: 1.
Lưu ý rằng các ký tự unicode 0-255 bao gồm các ký tự vô hình vô hình/kiểm soát (dòng mới, formfeed, dấu gạch nối mềm, v.v.) làm cho dữ liệu nhị phân của bạn gây phiền nhiễu khi xem trong trình chỉnh sửa văn bản.
Xem xét những hạn chế này, Tôi không khuyến nghị latin1 trừ khi bạn hiểu chính xác lý do bạn muốn.
Tôi chỉ đề cập đến nó như là mã hóa "tự nhiên" khác mà lò xo để tâm trí.
Nguồn
2010-04-11 17:23:27
Bạn nói rằng bạn có dữ liệu thô trong một str, làm cách nào bạn tạo dữ liệu đó ở địa điểm đầu tiên? Tôi giả sử bạn có một nguồn unicode một nơi nào đó, nhưng nó không rõ ràng với tôi nếu bạn đang viết unicode "thô" vào str, hoặc nếu bạn đang đọc nó từ một tập tin (như đối tượng) hoặc ... (Đăng chuỗi ví dụ thể hiện lỗi này sẽ hữu ích!) –