2009-12-03 68 views
20

Trong Python 3.x, một chuỗi bao gồm các mục Unicode thứ tự. (Xem báo giá từ tham chiếu ngôn ngữ bên dưới.) Biểu diễn bên trong của chuỗi Unicode là gì? Có phải là UTF-16 không?Biểu diễn nội bộ của chuỗi trong Python 3.x

Các mục của đối tượng chuỗi là Đơn vị mã Unicode. Mã Unicode đơn vị được biểu thị bằng một đối tượng chuỗi của một mục và có thể giữ giá trị 16 bit hoặc 32 bit đại diện cho một số Unicode (giá trị tối đa cho thứ tự được đưa ra trong sys.maxunicode, và phụ thuộc vào cách Python được định cấu hình tại thời gian biên dịch). Cặp thay thế có thể có mặt trong đối tượng Unicode và sẽ được báo cáo dưới dạng hai mục riêng biệt.

+1

Điều này có ý nghĩa gì? Vấn đề gì được giải quyết bằng cách biết các biểu diễn bên trong? –

+21

Tôi cảm thấy tôi học được nhiều hơn bằng cách đặt câu hỏi sai. – thebat

+2

Đây là câu hỏi hợp lệ, nếu không có lý do nào khác ngoài việc biết giá trị của 'ord ('העטלף')' sẽ là gì. – dotancohen

Trả lời

5

Đã có không có thay đổi trong biểu diễn nội bộ Unicode giữa Python 2.X và 3.X.

Đó chắc chắn KHÔNG phải là UTF-16. UTF-bất cứ điều gì là một đại diện bên ngoài theo định hướng byte.

Mỗi đơn vị mã (ký tự, thay thế, vv) đã được gán một số từ phạm vi (0, 2 ** 21). Điều này được gọi là "thứ tự" của nó.

Thực sự, tài liệu bạn trích dẫn đã nói lên tất cả. Hầu hết các mã nhị phân Python sử dụng các bit 16-bit, giới hạn bạn với Basic Multilingual Plane ("BMP") trừ khi bạn muốn muck về với người thay thế (tiện dụng nếu bạn không thể tìm thấy áo sơ mi tóc của bạn và giường của bạn là tắt rỉ sét). Để làm việc với các tiết mục Unicode đầy đủ, bạn muốn có một "xây dựng rộng" (rộng 32 bit).

Tóm lại, biểu diễn bên trong trong đối tượng unicode là một mảng các số nguyên không dấu 16 bit hoặc một mảng các số nguyên không dấu 32 bit (chỉ sử dụng 21 bit).

+15

"Lưu trữ các codepont unicode trong số nguyên 16 bit" được gọi là "UCS-2". Làm tương tự với các số nguyên 32 bit là UCS-4. –

+0

Tôi không chắc chắn làm thế nào nói rằng quá trình này được gọi là "UCS2" hoặc "garbelfratzing" hoặc bất cứ điều gì là giúp sự hiểu biết của OP. –

+13

gọi một cái gì đó bằng tên đúng của nó mang lại cho bạn một cái gì đó để ghi nhãn sự hiểu biết mới của bạn với và loại .. giữ nó cho đến khi bạn gặp lại. Chúng ta không thể nói mà không có lời nói. – u0b34a0f6ae

1

Phụ thuộc: xem here. Điều này vẫn đúng đối với Python 3 đến khi biểu diễn nội bộ đi.

0

Tôi nghĩ, Thật khó để đánh giá sự khác biệt giữa UTF-16, mà chỉ là một chuỗi các từ 16 bit, đối tượng chuỗi của Python.

Và Nếu python được biên dịch với tùy chọn Unicode = UCS4, nó sẽ được so sánh giữa UTF-32 và chuỗi Python.

Vì vậy, hãy xem xét tốt hơn, chúng nằm trong danh mục khác nhau, mặc dù bạn có thể biến đổi lẫn nhau.

5

Nhìn vào mã nguồn cho CPython 3.1.5, trong Include/unicodeobject.h:

/* --- Unicode Type ------------------------------------------------------- */ 

typedef struct { 
    PyObject_HEAD 
    Py_ssize_t length;   /* Length of raw Unicode data in buffer */ 
    Py_UNICODE *str;   /* Raw Unicode buffer */ 
    long hash;     /* Hash value; -1 if not set */ 
    int state;     /* != 0 if interned. In this case the two 
           * references from the dictionary to this object 
           * are *not* counted in ob_refcnt. */ 
    PyObject *defenc;   /* (Default) Encoded version as Python 
            string, or NULL; this is used for 
            implementing the buffer protocol */ 
} PyUnicodeObject; 

Các nhân vật được lưu trữ như một mảng của Py_UNICODE. Trên hầu hết các nền tảng, tôi tin rằng Py_UNICODE#define d là wchar_t.

23

Biểu diễn bên trong sẽ thay đổi trong Python 3.3 triển khai PEP 393. Đại diện mới sẽ chọn một hoặc một số ascii, latin-1, utf-8, utf-16, utf-32, thường cố gắng để có được một đại diện nhỏ gọn.

Chuyển đổi ngầm thành các cặp thay thế sẽ chỉ được thực hiện khi nói chuyện với API cũ (chỉ tồn tại trên cửa sổ, trong đó wchar_t là hai byte); chuỗi Python sẽ được giữ nguyên. Đây là số release notes.

+4

Trông tôi như PEP 393 nói rằng biểu diễn bên trong là nhỏ gọn nhất (cho một chuỗi cụ thể) của ASCII, Latin-1 (UCS1), UCS2 hoặc UCS4. Tức là: cụ thể KHÔNG utf-8/16/32. Lý do: Python phải là thời gian liên tục để lập chỉ mục thành một chuỗi, do đó các ký tự phải là kích thước đồng nhất, đó là trường hợp của UCS, nhưng không phải là biểu diễn utf. – gwideman

+0

PEP 393 nói tất cả ... –

+0

Latin-1 là một siêu của ASCII, vì vậy không có lý do gì để đưa ASCII vào làm một trong các tùy chọn. Các tùy chọn là (a) đồng nhất 8 bit, tức là Latin-1, (b) thống nhất 16 bit, tức là UCS2 hoặc (c) đồng nhất 32 bit, nghĩa là UCS4 (giống với UTF-32). Đáng chú ý là UTF-8 và UTF-16, không có số bit đồng đều trên mã số – JoelFan

4

Trong Python 3.3 trở lên, biểu diễn bên trong của chuỗi sẽ phụ thuộc vào chuỗi và có thể là bất kỳ ascii, latin-1, utf-8, utf-16, utf-32, như được ghi chú bởi Tobu và được mô tả trong PEP 393.

Đối với các Pythons trước đó, biểu diễn bên trong phụ thuộc vào cờ xây dựng của Python. Python có thể được xây dựng với các giá trị cờ --enable-unicode=ucs2 hoặc --enable-unicode=ucs4. ucs2 bản dựng thực tế là use UTF-16 as their internal representationucs4 xây dựng sử dụng UCS-4/UTF-32.

+1

Việc đọc PEP393 của tôi là biểu diễn bên trong không bao giờ là utf-8 hoặc bất kỳ mã hóa nào khác với số byte không phù hợp trên mỗi mã- điểm (ký hiệu) và tập hợp chính xác là: 'Latin-1',' UCS-2' hoặc 'UCS-4'. Không chắc tôi có quyền này. Tôi đọc rằng các hình thức utf-8 chỉ là đầu vào, hoặc trong một số trường hợp đầu ra được lưu vào bộ nhớ cache. –

Các vấn đề liên quan