Cách giải mã byte trong Python

HOWTO này thảo luận về sự hỗ trợ của Python đối với đặc tả Unicode để biểu diễn dữ liệu văn bản và giải thích các vấn đề khác nhau mà mọi người thường gặp phải khi cố gắng làm việc với Unicode

Giới thiệu về Unicode

Định nghĩa

Các chương trình ngày nay cần có khả năng xử lý nhiều loại ký tự. Các ứng dụng thường được quốc tế hóa để hiển thị thông báo và xuất ra nhiều ngôn ngữ do người dùng lựa chọn; . Nội dung web có thể được viết bằng bất kỳ ngôn ngữ nào trong số này và cũng có thể bao gồm nhiều biểu tượng cảm xúc. Kiểu chuỗi của Python sử dụng Tiêu chuẩn Unicode để biểu diễn các ký tự, cho phép các chương trình Python hoạt động với tất cả các ký tự có thể khác nhau này

Unicode (https. //www. unicode. org/) là một đặc điểm kỹ thuật nhằm mục đích liệt kê mọi ký tự được sử dụng bởi ngôn ngữ của con người và cung cấp cho mỗi ký tự một mã duy nhất của riêng nó. Các thông số kỹ thuật Unicode liên tục được sửa đổi và cập nhật để thêm các ngôn ngữ và ký hiệu mới

Một ký tự là thành phần nhỏ nhất có thể có của một văn bản. 'A', 'B', 'C', v.v. , đều là các ký tự khác nhau. 'È' và 'Í' cũng vậy. Các ký tự khác nhau tùy thuộc vào ngôn ngữ hoặc ngữ cảnh mà bạn đang nói đến. Ví dụ: có một ký tự cho “Số một La Mã”, 'Ⅰ', tách biệt với chữ hoa 'I'. Chúng thường trông giống nhau, nhưng đây là hai ký tự khác nhau có ý nghĩa khác nhau

Tiêu chuẩn Unicode mô tả cách các ký tự được biểu thị bằng các điểm mã. Giá trị điểm mã là một số nguyên trong phạm vi từ 0 đến 0x10FFFF (khoảng 1. 1 triệu giá trị, ít hơn thế). Trong tiêu chuẩn và trong tài liệu này, một điểm mã được viết bằng cách sử dụng ký hiệu

try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
4 để chỉ ký tự có giá trị
try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
5 (9,822 ở dạng thập phân)

Tiêu chuẩn Unicode chứa rất nhiều bảng liệt kê các ký tự và điểm mã tương ứng của chúng

0061    'a'; LATIN SMALL LETTER A
0062    'b'; LATIN SMALL LETTER B
0063    'c'; LATIN SMALL LETTER C
...
007B    '{'; LEFT CURLY BRACKET
...
2167    'Ⅷ'; ROMAN NUMERAL EIGHT
2168    'Ⅸ'; ROMAN NUMERAL NINE
...
265E    '♞'; BLACK CHESS KNIGHT
265F    '♟'; BLACK CHESS PAWN
...
1F600   '😀'; GRINNING FACE
1F609   '😉'; WINKING FACE
...

Nghiêm túc mà nói, những định nghĩa này ngụ ý rằng thật vô nghĩa khi nói 'đây là ký tự

try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
4'.
try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
4 là một điểm mã, đại diện cho một số ký tự cụ thể; . Trong bối cảnh không chính thức, sự khác biệt này giữa các điểm mã và ký tự đôi khi sẽ bị lãng quên

Một ký tự được thể hiện trên màn hình hoặc trên giấy bằng một tập hợp các thành phần đồ họa được gọi là glyph. Ví dụ, nét chữ cho chữ hoa A là hai nét chéo và một nét ngang, mặc dù các chi tiết chính xác sẽ phụ thuộc vào phông chữ được sử dụng. Hầu hết các mã Python không cần phải lo lắng về glyphs;

mã hóa

Để tóm tắt phần trước. một chuỗi Unicode là một chuỗi các điểm mã, là các số từ 0 đến

try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
8 (1.114.111 thập phân). Chuỗi điểm mã này cần được biểu diễn trong bộ nhớ dưới dạng một tập hợp các đơn vị mã và sau đó các đơn vị mã được ánh xạ tới các byte 8 bit. Các quy tắc để dịch một chuỗi Unicode thành một chuỗi byte được gọi là mã hóa ký tự hoặc chỉ là mã hóa

Mã hóa đầu tiên bạn có thể nghĩ đến là sử dụng số nguyên 32 bit làm đơn vị mã, sau đó sử dụng biểu diễn của CPU về số nguyên 32 bit. Trong biểu diễn này, chuỗi “Python” có thể trông như thế này

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Biểu diễn này rất đơn giản nhưng sử dụng nó gây ra một số vấn đề

  1. Nó không di động;

  2. Rất lãng phí không gian. Trong hầu hết các văn bản, phần lớn các điểm mã nhỏ hơn 127 hoặc nhỏ hơn 255, vì vậy rất nhiều không gian bị chiếm dụng bởi

    try:
        with open('/tmp/input.txt', 'r') as f:
            ...
    except OSError:
        # 'File not found' error message.
        print("Fichier non trouvé")
    
    9 byte. Chuỗi trên chiếm 24 byte so với 6 byte cần thiết cho biểu diễn ASCII. Mức sử dụng RAM tăng lên không quá quan trọng (máy tính để bàn có RAM hàng gigabyte và các chuỗi thường không lớn như vậy), nhưng việc mở rộng mức sử dụng băng thông mạng và đĩa của chúng tôi lên hệ số 4 là không thể chấp nhận được

  3. Nó không tương thích với các hàm C hiện có như

    répertoire = "/tmp/records.log"
    with open(répertoire, "w") as f:
        f.write("test\n")
    
    0, vì vậy cần phải sử dụng một nhóm hàm chuỗi rộng mới

Do đó, bảng mã này không được sử dụng nhiều và thay vào đó mọi người chọn các bảng mã khác hiệu quả và tiện lợi hơn, chẳng hạn như UTF-8

UTF-8 là một trong những bảng mã được sử dụng phổ biến nhất và Python thường mặc định sử dụng nó. UTF là viết tắt của "Định dạng chuyển đổi Unicode" và '8' có nghĩa là các giá trị 8 bit được sử dụng trong mã hóa. (Cũng có bảng mã UTF-16 và UTF-32, nhưng chúng ít được sử dụng hơn UTF-8. ) UTF-8 sử dụng các quy tắc sau

  1. Nếu điểm mã < 128, thì nó được biểu thị bằng giá trị byte tương ứng

  2. Nếu điểm mã >= 128, thì nó được chuyển thành một chuỗi gồm hai, ba hoặc bốn byte, trong đó mỗi byte của chuỗi nằm trong khoảng từ 128 đến 255

UTF-8 có một số thuộc tính tiện lợi

  1. Nó có thể xử lý bất kỳ điểm mã Unicode nào

  2. Một chuỗi Unicode được biến thành một chuỗi byte chỉ chứa các byte 0 được nhúng khi chúng đại diện cho ký tự null (U+0000). Điều này có nghĩa là các chuỗi UTF-8 có thể được xử lý bởi các hàm C chẳng hạn như

    répertoire = "/tmp/records.log"
    with open(répertoire, "w") as f:
        f.write("test\n")
    
    1 và được gửi qua các giao thức không thể xử lý các byte bằng 0 cho bất kỳ thứ gì khác ngoài các điểm đánh dấu cuối chuỗi

  3. Một chuỗi văn bản ASCII cũng là văn bản UTF-8 hợp lệ

  4. UTF-8 khá nhỏ gọn;

  5. Nếu byte bị hỏng hoặc bị mất, có thể xác định điểm bắt đầu của điểm mã được mã hóa UTF-8 tiếp theo và đồng bộ hóa lại. Cũng không chắc rằng dữ liệu 8-bit ngẫu nhiên sẽ giống như UTF-8 hợp lệ

  6. UTF-8 là mã hóa hướng byte. Mã hóa chỉ định rằng mỗi ký tự được biểu thị bằng một chuỗi cụ thể gồm một hoặc nhiều byte. Điều này giúp tránh các vấn đề về thứ tự byte có thể xảy ra với mã hóa hướng số nguyên và từ, như UTF-16 và UTF-32, trong đó chuỗi byte thay đổi tùy thuộc vào phần cứng mà chuỗi được mã hóa

Người giới thiệu

Trang Unicode Consortium có các biểu đồ ký tự, bảng thuật ngữ và các phiên bản PDF của đặc tả Unicode. Hãy chuẩn bị cho một số bài đọc khó. Niên đại về nguồn gốc và sự phát triển của Unicode cũng có sẵn trên trang web

Trên kênh Youtube Computerphile, Tom Scott nói ngắn gọn về lịch sử của Unicode và UTF-8 (9 phút 36 giây)

Để giúp hiểu tiêu chuẩn, Jukka Korpela đã viết một hướng dẫn giới thiệu để đọc các bảng ký tự Unicode

Một bài giới thiệu hay khác được viết bởi Joel Spolsky. Nếu phần giới thiệu này không làm rõ mọi thứ với bạn, bạn nên thử đọc bài viết thay thế này trước khi tiếp tục

Các mục Wikipedia thường hữu ích;

Hỗ trợ Unicode của Python

Bây giờ bạn đã học những kiến ​​thức cơ bản về Unicode, chúng ta có thể xem xét các tính năng Unicode của Python

Loại chuỗi

Kể từ Python 3. 0, loại ngôn ngữ chứa các ký tự Unicode, nghĩa là bất kỳ chuỗi nào được tạo bằng cách sử dụng

répertoire = "/tmp/records.log"
with open(répertoire, "w") as f:
    f.write("test\n")
3,
répertoire = "/tmp/records.log"
with open(répertoire, "w") as f:
    f.write("test\n")
4 hoặc cú pháp chuỗi trích dẫn ba lần được lưu trữ dưới dạng Unicode

Mã hóa mặc định cho mã nguồn Python là UTF-8, vì vậy bạn chỉ cần đưa một ký tự Unicode vào một chuỗi ký tự

try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")

lưu ý bên lề. Python 3 cũng hỗ trợ sử dụng các ký tự Unicode trong mã định danh

________số 8_______

Nếu bạn không thể nhập một ký tự cụ thể trong trình chỉnh sửa của mình hoặc muốn giữ mã nguồn chỉ ở dạng ASCII vì lý do nào đó, bạn cũng có thể sử dụng các chuỗi thoát trong chuỗi ký tự. (Tùy thuộc vào hệ thống của bạn, bạn có thể thấy nét chữ hoa-đồng bằng thực tế thay vì chữ u thoát. )

>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'

Ngoài ra, người ta có thể tạo một chuỗi bằng cách sử dụng phương pháp. Phương thức này nhận một đối số mã hóa, chẳng hạn như

répertoire = "/tmp/records.log"
with open(répertoire, "w") as f:
    f.write("test\n")
7 và tùy chọn một đối số lỗi

Đối số lỗi chỉ định phản hồi khi chuỗi đầu vào không thể được chuyển đổi theo quy tắc mã hóa. Các giá trị pháp lý cho đối số này là

répertoire = "/tmp/records.log"
with open(répertoire, "w") as f:
    f.write("test\n")
8 (nêu một ngoại lệ),
>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'
0 (sử dụng
>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'
1,
>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'
2),
>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'
3 (chỉ cần bỏ ký tự ra khỏi kết quả Unicode), hoặc
>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'
4 (chèn chuỗi thoát
>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'
5). Các ví dụ sau đây cho thấy sự khác biệt

>>> b'\x80abc'.decode("utf-8", "strict")  
Traceback (most recent call last):
    ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0:
  invalid start byte
>>> b'\x80abc'.decode("utf-8", "replace")
'\ufffdabc'
>>> b'\x80abc'.decode("utf-8", "backslashreplace")
'\\x80abc'
>>> b'\x80abc'.decode("utf-8", "ignore")
'abc'

Mã hóa được chỉ định dưới dạng chuỗi chứa tên mã hóa. Python đi kèm với khoảng 100 bảng mã khác nhau; . Một số bảng mã có nhiều tên;

Chuỗi Unicode một ký tự cũng có thể được tạo bằng hàm tích hợp, lấy số nguyên và trả về chuỗi Unicode có độ dài 1 chứa điểm mã tương ứng. Thao tác ngược lại là hàm tích hợp nhận chuỗi Unicode một ký tự và trả về giá trị điểm mã

>>> chr(57344)
'\ue000'
>>> ord('\ue000')
57344

Chuyển đổi sang byte

Phương thức ngược lại của is , trả về một đại diện của chuỗi Unicode, được mã hóa theo mã hóa được yêu cầu

Tham số lỗi giống như tham số của phương thức nhưng hỗ trợ thêm một số trình xử lý có thể. Cũng như

répertoire = "/tmp/records.log"
with open(répertoire, "w") as f:
    f.write("test\n")
8,
>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'
3 và
>>> "\N{GREEK CAPITAL LETTER DELTA}"  # Using the character name
'\u0394'
>>> "\u0394"                          # Using a 16-bit hex value
'\u0394'
>>> "\U00000394"                      # Using a 32-bit hex value
'\u0394'
0 (trong trường hợp này chèn một dấu chấm hỏi thay vì ký tự không thể mã hóa), cũng có
>>> b'\x80abc'.decode("utf-8", "strict")  
Traceback (most recent call last):
    ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0:
  invalid start byte
>>> b'\x80abc'.decode("utf-8", "replace")
'\ufffdabc'
>>> b'\x80abc'.decode("utf-8", "backslashreplace")
'\\x80abc'
>>> b'\x80abc'.decode("utf-8", "ignore")
'abc'
8 (chèn một tham chiếu ký tự XML),
>>> b'\x80abc'.decode("utf-8", "strict")  
Traceback (most recent call last):
    ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0:
  invalid start byte
>>> b'\x80abc'.decode("utf-8", "replace")
'\ufffdabc'
>>> b'\x80abc'.decode("utf-8", "backslashreplace")
'\\x80abc'
>>> b'\x80abc'.decode("utf-8", "ignore")
'abc'
9 (chèn một chuỗi thoát
>>> chr(57344)
'\ue000'
>>> ord('\ue000')
57344
0) và
>>> chr(57344)
'\ue000'
>>> ord('\ue000')
57344
1 (chèn một

Ví dụ sau đây cho thấy các kết quả khác nhau

>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')  
Traceback (most recent call last):
    ...
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
  position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
b'ꀀabcd޴'
>>> u.encode('ascii', 'backslashreplace')
b'\\ua000abcd\\u07b4'
>>> u.encode('ascii', 'namereplace')
b'\\N{YI SYLLABLE IT}abcd\\u07b4'

Các quy trình cấp thấp để đăng ký và truy cập các mã hóa có sẵn được tìm thấy trong mô-đun. Việc triển khai mã hóa mới cũng yêu cầu hiểu mô-đun. Tuy nhiên, các chức năng mã hóa và giải mã do mô-đun này trả về thường ở mức độ thấp hơn là thoải mái và việc viết mã hóa mới là một nhiệm vụ chuyên biệt, vì vậy mô-đun sẽ không được đề cập trong tài liệu HOWTO này

Chữ Unicode trong mã nguồn Python

Trong mã nguồn Python, các điểm mã Unicode cụ thể có thể được viết bằng cách sử dụng chuỗi thoát

>>> chr(57344)
'\ue000'
>>> ord('\ue000')
57344
5, theo sau là bốn chữ số thập lục phân cho điểm mã. Chuỗi thoát
>>> chr(57344)
'\ue000'
>>> ord('\ue000')
57344
6 tương tự, nhưng mong đợi tám chữ số hex, không phải bốn

>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]

Sử dụng chuỗi thoát cho các điểm mã lớn hơn 127 là tốt với liều lượng nhỏ, nhưng sẽ gây khó chịu nếu bạn đang sử dụng nhiều ký tự có dấu, giống như trong một chương trình có thông báo bằng tiếng Pháp hoặc một số ngôn ngữ sử dụng dấu khác. Bạn cũng có thể tập hợp các chuỗi bằng hàm có sẵn, nhưng điều này thậm chí còn tẻ nhạt hơn

Lý tưởng nhất là bạn muốn có thể viết chữ bằng mã hóa tự nhiên của ngôn ngữ của mình. Sau đó, bạn có thể chỉnh sửa mã nguồn Python bằng trình chỉnh sửa yêu thích của mình, trình chỉnh sửa này sẽ hiển thị các ký tự có dấu một cách tự nhiên và có các ký tự phù hợp được sử dụng khi chạy

Python hỗ trợ viết mã nguồn bằng UTF-8 theo mặc định, nhưng bạn có thể sử dụng hầu hết mọi mã hóa nếu bạn khai báo mã hóa đang được sử dụng. Điều này được thực hiện bằng cách bao gồm một nhận xét đặc biệt ở dòng đầu tiên hoặc dòng thứ hai của tệp nguồn

#!/usr/bin/env python
# -*- coding: latin-1 -*-

u = 'abcdé'
print(ord(u[-1]))

Cú pháp được lấy cảm hứng từ ký hiệu của Emacs để chỉ định các biến cục bộ cho một tệp. Emacs hỗ trợ nhiều biến khác nhau, nhưng Python chỉ hỗ trợ 'viết mã'. Các ký hiệu

>>> chr(57344)
'\ue000'
>>> ord('\ue000')
57344
8 cho Emacs biết rằng nhận xét đó là đặc biệt; . Python tìm kiếm
>>> chr(57344)
'\ue000'
>>> ord('\ue000')
57344
9 hoặc
>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')  
Traceback (most recent call last):
    ...
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
  position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
b'ꀀabcd޴'
>>> u.encode('ascii', 'backslashreplace')
b'\\ua000abcd\\u07b4'
>>> u.encode('ascii', 'namereplace')
b'\\N{YI SYLLABLE IT}abcd\\u07b4'
0 trong bình luận

Nếu bạn không bao gồm nhận xét như vậy, mã hóa mặc định được sử dụng sẽ là UTF-8 như đã đề cập. Xem thêm PEP 263 để biết thêm thông tin

Thuộc tính Unicode

Đặc tả Unicode bao gồm một cơ sở dữ liệu thông tin về các điểm mã. Đối với mỗi điểm mã được xác định, thông tin bao gồm tên của ký tự, loại của nó, giá trị số nếu có (đối với các ký tự đại diện cho các khái niệm số như chữ số La Mã, phân số như một phần ba và bốn phần năm, v.v. ). Ngoài ra còn có các thuộc tính liên quan đến hiển thị, chẳng hạn như cách sử dụng điểm mã trong văn bản hai chiều

Chương trình sau hiển thị một số thông tin về một số ký tự và in giá trị số của một ký tự cụ thể

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
0

Khi chạy, bản in này

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
1

Mã danh mục là chữ viết tắt mô tả bản chất của ký tự. Chúng được nhóm thành các danh mục như “Thư”, “Số”, “Dấu chấm câu” hoặc “Ký hiệu”, lần lượt được chia thành các danh mục con. Để lấy các mã từ đầu ra ở trên,

>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')  
Traceback (most recent call last):
    ...
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
  position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
b'ꀀabcd޴'
>>> u.encode('ascii', 'backslashreplace')
b'\\ua000abcd\\u07b4'
>>> u.encode('ascii', 'namereplace')
b'\\N{YI SYLLABLE IT}abcd\\u07b4'
1 có nghĩa là 'Chữ cái, chữ thường',
>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')  
Traceback (most recent call last):
    ...
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
  position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
b'ꀀabcd޴'
>>> u.encode('ascii', 'backslashreplace')
b'\\ua000abcd\\u07b4'
>>> u.encode('ascii', 'namereplace')
b'\\N{YI SYLLABLE IT}abcd\\u07b4'
2 có nghĩa là "Số, khác",
>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')  
Traceback (most recent call last):
    ...
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
  position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
b'ꀀabcd޴'
>>> u.encode('ascii', 'backslashreplace')
b'\\ua000abcd\\u07b4'
>>> u.encode('ascii', 'namereplace')
b'\\N{YI SYLLABLE IT}abcd\\u07b4'
3 là "Dấu, không cách" và
>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')  
Traceback (most recent call last):
    ...
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
  position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
b'ꀀabcd޴'
>>> u.encode('ascii', 'backslashreplace')
b'\\ua000abcd\\u07b4'
>>> u.encode('ascii', 'namereplace')
b'\\N{YI SYLLABLE IT}abcd\\u07b4'
4 là "Ký hiệu, khác". Xem danh sách mã danh mục

So sánh chuỗi

Unicode thêm một số phức tạp để so sánh các chuỗi, bởi vì cùng một bộ ký tự có thể được biểu thị bằng các chuỗi điểm mã khác nhau. Ví dụ: một chữ cái như 'ê' có thể được biểu thị dưới dạng một điểm mã U+00EA hoặc U+0065 U+0302, là điểm mã cho 'e' theo sau là điểm mã cho 'DẤU VÒNG KẾT HỢP'. Chúng sẽ tạo ra cùng một đầu ra khi được in, nhưng một là chuỗi có độ dài 1 và chuỗi kia có độ dài 2

Một công cụ để so sánh không phân biệt chữ hoa chữ thường là phương thức chuỗi chuyển đổi một chuỗi thành dạng không phân biệt chữ hoa chữ thường theo thuật toán được mô tả bởi Tiêu chuẩn Unicode. Thuật toán này có cách xử lý đặc biệt đối với các ký tự như chữ cái tiếng Đức 'ß' (điểm mã U+00DF), ký tự này trở thành cặp chữ cái viết thường 'ss'

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
2

Công cụ thứ hai là chức năng của mô-đun chuyển đổi các chuỗi thành một trong số các dạng thông thường, trong đó các chữ cái theo sau bởi một ký tự kết hợp được thay thế bằng các ký tự đơn lẻ.

>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')  
Traceback (most recent call last):
    ...
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
  position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
b'ꀀabcd޴'
>>> u.encode('ascii', 'backslashreplace')
b'\\ua000abcd\\u07b4'
>>> u.encode('ascii', 'namereplace')
b'\\N{YI SYLLABLE IT}abcd\\u07b4'
7 có thể được sử dụng để thực hiện so sánh chuỗi sẽ không báo cáo sai bất đẳng thức nếu hai chuỗi sử dụng các ký tự kết hợp khác nhau

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
3

Khi chạy, kết quả này xuất ra

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
4

Đối số đầu tiên của hàm là một chuỗi cung cấp dạng chuẩn hóa mong muốn, có thể là một trong 'NFC', 'NFKC', 'NFD' và 'NFKD'

Tiêu chuẩn Unicode cũng chỉ định cách thực hiện so sánh không phân biệt chữ hoa chữ thường

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
5

Điều này sẽ in

>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
0. (Tại sao
>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
1 được gọi hai lần? Vì có một số ký tự khiến cho
>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')  
Traceback (most recent call last):
    ...
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in
  position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
b'ꀀabcd޴'
>>> u.encode('ascii', 'backslashreplace')
b'\\ua000abcd\\u07b4'
>>> u.encode('ascii', 'namereplace')
b'\\N{YI SYLLABLE IT}abcd\\u07b4'
5 trả về một chuỗi không chuẩn hóa nên kết quả cần được chuẩn hóa lại. Xem phần 3. 13 của Tiêu chuẩn Unicode để thảo luận và ví dụ. )

Biểu thức chính quy Unicode

Các biểu thức chính quy được mô-đun hỗ trợ có thể được cung cấp dưới dạng byte hoặc chuỗi. Một số chuỗi ký tự đặc biệt như

>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
4 và
>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
5 có ý nghĩa khác nhau tùy thuộc vào việc mẫu được cung cấp dưới dạng byte hay chuỗi. Ví dụ:
>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
4 sẽ khớp với các ký tự
>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
7 theo byte nhưng trong chuỗi sẽ khớp với bất kỳ ký tự nào trong danh mục
>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
8

Chuỗi trong ví dụ này có số 57 được viết bằng cả chữ số Thái Lan và Ả Rập

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
6

Khi thực hiện,

>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
9 sẽ khớp với các chữ số Thái Lan và in chúng ra. Nếu bạn cung cấp cờ cho , thì thay vào đó,
>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
9 sẽ khớp với chuỗi con “57”

Tương tự,

>>> s = "a\xac\u1234\u20ac\U00008000"
.. #     ^^^^ two-digit hex escape
.. #         ^^^^^^ four-digit Unicode escape
.. #                     ^^^^^^^^^^ eight-digit Unicode escape
>>> [ord(c) for c in s]
[97, 172, 4660, 8364, 32768]
5 khớp với nhiều ký tự Unicode khác nhau nhưng chỉ
#!/usr/bin/env python
# -*- coding: latin-1 -*-

u = 'abcdé'
print(ord(u[-1]))
4 theo byte hoặc nếu được cung cấp và
#!/usr/bin/env python
# -*- coding: latin-1 -*-

u = 'abcdé'
print(ord(u[-1]))
6 sẽ khớp với ký tự khoảng trắng Unicode hoặc
#!/usr/bin/env python
# -*- coding: latin-1 -*-

u = 'abcdé'
print(ord(u[-1]))
7

Người giới thiệu

Một số cuộc thảo luận thay thế tốt về hỗ trợ Unicode của Python là

  • Xử lý tệp văn bản trong Python 3, bởi Nick Coghlan

  • Pragmatic Unicode, một bản trình bày PyCon 2012 của Ned Batchelder

Loại được mô tả trong tài liệu tham khảo thư viện Python tại

Tài liệu về mô-đun

Tài liệu về mô-đun

Marc-André Lemburg đã thuyết trình với tiêu đề “Python và Unicode” (PDF slide) tại EuroPython 2002. Các trang trình bày là một tổng quan tuyệt vời về thiết kế các tính năng Unicode của Python 2 (trong đó loại chuỗi Unicode được gọi là

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
01 và chữ bắt đầu bằng
   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
02)

Đọc và ghi dữ liệu Unicode

Khi bạn đã viết một số mã hoạt động với dữ liệu Unicode, vấn đề tiếp theo là đầu vào/đầu ra. Làm cách nào để bạn đưa các chuỗi Unicode vào chương trình của mình và làm cách nào để chuyển đổi Unicode thành một dạng phù hợp để lưu trữ hoặc truyền tải?

Có thể bạn không cần phải làm bất cứ điều gì tùy thuộc vào nguồn đầu vào và đích đầu ra của bạn; . Trình phân tích cú pháp XML thường trả về dữ liệu Unicode, ví dụ. Nhiều cơ sở dữ liệu quan hệ cũng hỗ trợ các cột có giá trị Unicode và có thể trả về các giá trị Unicode từ truy vấn SQL

Dữ liệu Unicode thường được chuyển đổi thành một mã hóa cụ thể trước khi được ghi vào đĩa hoặc gửi qua ổ cắm. Có thể tự mình làm tất cả công việc. mở một tệp, đọc một đối tượng byte 8 bit từ tệp đó và chuyển đổi các byte bằng

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
03. Tuy nhiên, cách tiếp cận thủ công không được khuyến khích

Một vấn đề là bản chất mã hóa nhiều byte; . Nếu bạn muốn đọc tệp theo các khối có kích thước tùy ý (ví dụ: 1024 hoặc 4096 byte), bạn cần viết mã xử lý lỗi để nắm bắt trường hợp chỉ một phần của byte mã hóa một ký tự Unicode được đọc ở cuối tệp. . Một giải pháp là đọc toàn bộ tệp vào bộ nhớ và sau đó thực hiện giải mã, nhưng điều đó ngăn cản bạn làm việc với các tệp cực lớn; . (Hơn nữa, thực sự, vì trong ít nhất một lúc, bạn cần có cả chuỗi được mã hóa và phiên bản Unicode của nó trong bộ nhớ. )

Giải pháp sẽ là sử dụng giao diện giải mã cấp thấp để nắm bắt trường hợp trình tự mã hóa một phần. Công việc thực hiện điều này đã được thực hiện cho bạn. hàm tích hợp có thể trả về một đối tượng giống như tệp giả sử nội dung của tệp ở dạng mã hóa được chỉ định và chấp nhận các tham số Unicode cho các phương thức như và. Điều này hoạt động thông qua các tham số mã hóa và lỗi được diễn giải giống như các tham số trong và

Do đó, việc đọc Unicode từ một tệp rất đơn giản

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
7

Cũng có thể mở tệp ở chế độ cập nhật, cho phép đọc và ghi

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
8

Ký tự Unicode

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
10 được sử dụng làm dấu thứ tự byte (BOM) và thường được viết làm ký tự đầu tiên của tệp để hỗ trợ tự động phát hiện thứ tự byte của tệp. Một số mã hóa, chẳng hạn như UTF-16, yêu cầu BOM xuất hiện ở đầu tệp; . Có các biến thể của các mã hóa này, chẳng hạn như 'utf-16-le' và 'utf-16-be' đối với mã hóa little-endian và big-endian, chỉ định một thứ tự byte cụ thể và không bỏ qua BOM

Ở một số khu vực, người ta cũng quy ước sử dụng “BOM” ở đầu các tệp được mã hóa UTF-8; . Dấu chỉ đơn giản thông báo rằng tệp được mã hóa bằng UTF-8. Để đọc các tệp như vậy, hãy sử dụng codec 'utf-8-sig' để tự động bỏ qua dấu nếu có

tên tệp Unicode

Hầu hết các hệ điều hành được sử dụng phổ biến hiện nay đều hỗ trợ tên tệp chứa các ký tự Unicode tùy ý. Thông thường, điều này được thực hiện bằng cách chuyển đổi chuỗi Unicode thành một số mã hóa khác nhau tùy thuộc vào hệ thống. Hôm nay Python đang tập trung vào việc sử dụng UTF-8. Python trên MacOS đã sử dụng UTF-8 cho một số phiên bản và Python 3. 6 cũng chuyển sang sử dụng UTF-8 trên Windows. Trên các hệ thống Unix, sẽ chỉ có một. nếu bạn đã đặt các biến môi trường

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
11 hoặc
   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
12;

Hàm trả về mã hóa để sử dụng trên hệ thống hiện tại của bạn, trong trường hợp bạn muốn thực hiện mã hóa theo cách thủ công nhưng không có nhiều lý do để bận tâm. Khi mở một tệp để đọc hoặc ghi, thông thường bạn chỉ cần cung cấp chuỗi Unicode làm tên tệp và nó sẽ tự động được chuyển đổi sang bảng mã phù hợp với bạn

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
9

Các chức năng trong mô-đun như cũng sẽ chấp nhận tên tệp Unicode

Hàm trả về tên tệp, điều này gây ra sự cố. nó nên trả về phiên bản Unicode của tên tệp hay nó nên trả về các byte chứa các phiên bản được mã hóa? . Nếu bạn chuyển một chuỗi Unicode làm đường dẫn, tên tệp sẽ được giải mã bằng mã hóa của hệ thống tệp và một danh sách các chuỗi Unicode sẽ được trả về, trong khi chuyển một đường dẫn byte sẽ trả về tên tệp dưới dạng byte. Ví dụ: giả sử mặc định là UTF-8, hãy chạy chương trình sau

try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
0

sẽ tạo ra đầu ra sau

try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
1

Danh sách đầu tiên chứa tên tệp được mã hóa UTF-8 và danh sách thứ hai chứa các phiên bản Unicode

Lưu ý rằng trong hầu hết các trường hợp, bạn chỉ nên sử dụng Unicode với các API này. API byte chỉ nên được sử dụng trên các hệ thống có tên tệp không thể giải mã được;

Mẹo viết chương trình nhận biết Unicode

Phần này cung cấp một số gợi ý về cách viết phần mềm xử lý Unicode

Mẹo quan trọng nhất là

Phần mềm chỉ nên hoạt động với các chuỗi Unicode bên trong, giải mã dữ liệu đầu vào càng sớm càng tốt và chỉ mã hóa đầu ra khi kết thúc

Nếu bạn cố gắng viết các hàm xử lý chấp nhận cả chuỗi Unicode và chuỗi byte, bạn sẽ thấy chương trình của mình dễ bị lỗi bất cứ khi nào bạn kết hợp hai loại chuỗi khác nhau. Không có mã hóa hoặc giải mã tự động. nếu bạn làm e. g.

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
18, ý chí được nêu ra

Khi sử dụng dữ liệu đến từ trình duyệt web hoặc một số nguồn không đáng tin cậy khác, một kỹ thuật phổ biến là kiểm tra các ký tự không hợp lệ trong chuỗi trước khi sử dụng chuỗi trong dòng lệnh được tạo hoặc lưu trữ trong cơ sở dữ liệu. Nếu bạn đang làm điều này, hãy cẩn thận kiểm tra chuỗi đã giải mã, không phải dữ liệu byte được mã hóa; . Điều này đặc biệt đúng nếu dữ liệu đầu vào cũng chỉ định mã hóa, vì sau đó kẻ tấn công có thể chọn một cách thông minh để ẩn văn bản độc hại trong dòng byte được mã hóa

Chuyển đổi giữa các mã hóa tệp

Lớp có thể chuyển đổi rõ ràng giữa các mã hóa, lấy luồng trả về dữ liệu ở mã hóa #1 và hoạt động giống như luồng trả về dữ liệu ở mã hóa #2

Ví dụ: nếu bạn có tệp đầu vào f ở dạng Latinh-1, bạn có thể bọc tệp đó bằng a để trả về các byte được mã hóa bằng UTF-8

try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
2

Tệp trong mã hóa không xác định

Bạn có thể làm gì nếu cần thực hiện thay đổi đối với tệp nhưng không biết mã hóa của tệp?

try:
    with open('/tmp/input.txt', 'r') as f:
        ...
except OSError:
    # 'File not found' error message.
    print("Fichier non trouvé")
3

Trình xử lý lỗi

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
22 sẽ giải mã bất kỳ byte không phải ASCII nào dưới dạng các điểm mã trong một phạm vi đặc biệt chạy từ U+DC80 đến U+DCFF. Sau đó, các điểm mã này sẽ trở lại thành các byte giống nhau khi trình xử lý lỗi
   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
22 được sử dụng để mã hóa dữ liệu và ghi lại dữ liệu đó

Người giới thiệu

Một phần của Mastering Python 3 Input/Output, một bài nói chuyện về PyCon 2010 của David Beazley, thảo luận về xử lý văn bản và xử lý dữ liệu nhị phân

Các slide PDF cho bài thuyết trình của Marc-André Lemburg “Viết ứng dụng nhận biết Unicode bằng Python” thảo luận về các câu hỏi về mã hóa ký tự cũng như cách quốc tế hóa và bản địa hóa ứng dụng. Các slide này bao gồm Python 2. chỉ x

The Guts of Unicode in Python là một bài nói chuyện tại PyCon 2013 của Benjamin Peterson thảo luận về cách biểu diễn Unicode bên trong trong Python 3. 3

Sự nhìn nhận

Bản thảo đầu tiên của tài liệu này được viết bởi Andrew Kuchling. Kể từ đó, nó đã được sửa đổi thêm bởi Alexander Belopolsky, Georg Brandl, Andrew Kuchling và Ezio Melotti

Cảm ơn những người sau đây đã lưu ý lỗi hoặc đưa ra đề xuất về bài viết này. Éric Araujo, Nicholas Bastin, Nick Coghlan, Marius Gedminas, Kent Johnson, Ken Krugler, Marc-André Lemburg, Martin von Löwis, Terry J. Diễn viên: ReedySerhiy StorchakaEryk SunChad WhitacreGraham Wideman

Làm cách nào để đọc byte trong Python?

bạn có thể sử dụng bin(ord('b')) . replace('b', '') bin() nó cung cấp cho bạn biểu diễn nhị phân với 'b' sau bit cuối cùng, bạn phải xóa nó. Ngoài ra, ord() cung cấp cho bạn số ASCII cho ký tự được mã hóa char hoặc 8-bit/1 Byte. Lưu câu trả lời này.

Làm cách nào để giải mã mảng byte trong Python?

Sử dụng hàm decode() để chuyển đổi Bytearray thành String trong Python. Một cách khác để chuyển đổi một mảng phụ thành chuỗi là sử dụng phương thức decode(). Phương thức giải mã (), khi được gọi trên một đối tượng bytearray, sẽ lấy định dạng mã hóa làm đầu vào và trả về chuỗi đầu ra.