2009-12-03 16 views
20

En Python 3.x, una secuencia consiste en artículos del ordinal de Unicode. (Consulte la cita de la referencia de idioma a continuación). ¿Cuál es la representación interna de la cadena Unicode? ¿Es UTF-16?Cuál es la representación interna de la secuencia en Python 3.x

Los elementos de un objeto de cadena son unidades de código Unicode. Una unidad Unicode código está representada por un objeto de cadena de un artículo y puede contener o bien un 16 bits o valor de 32 bits que representa un Unicode ordinal (el valor máximo para el ordinal se da en sys.maxunicode, y depende de cómo se configure Python en tiempo de compilación). Los pares sustituidos pueden estar presentes en el objeto Unicode , y se informará como dos elementos separados.

+1

¿Qué significa esto? ¿Qué problema se resuelve conociendo las representaciones internas? –

+21

Siento que aprendo más haciendo la pregunta incorrecta. – thebat

+2

Esta es una pregunta válida, solo por conocer el valor de 'ord ('העטלף')'. – dotancohen

Respuesta

5

No ha habido NINGÚN CAMBIO en la representación interna de Unicode entre Python 2.X y 3.X.

Definitivamente NO es UTF-16. UTF-anything es una representación EXTERNA orientada a bytes.

A cada unidad de código (carácter, sustituto, etc.) se le ha asignado un número del rango (0, 2 ** 21). Esto se llama su "ordinal".

Realmente, la documentación que citó lo dice todo. La mayoría de los binarios de Python usan ordinales de 16 bits que lo restringen al plano multilingüe básico ("BMP") a menos que quiera ensuciarlo con sustitutos (a mano si no puede encontrar su camisa de pelo y su cama de clavos está desactivada). oxidado). Para trabajar con el repertorio completo de Unicode, preferiría una "construcción amplia" (32 bits de ancho).

En pocas palabras, la representación interna en un objeto Unicode es una matriz de enteros sin signo de 16 bits, o una matriz de enteros sin signo de 32 bits (con solo 21 bits).

+15

"Almacenar los codeponts Unicode en enteros de 16 bits" se llama "UCS-2". Hacer lo mismo con enteros de 32 bits es UCS-4. –

+0

No estoy seguro de cómo decir que el proceso se llama "UCS2" o "garbelfratzing" o lo que sea que esté ayudando al entendimiento del OP. –

+13

llamar a algo por su nombre correcto le da algo para etiquetar su nueva comprensión y más o menos ... mantenerla hasta que vuelva a encontrarse. No podemos hablar sin palabras – u0b34a0f6ae

1

Depende: vea here. Esto sigue siendo cierto para Python 3 en lo que respecta a la representación interna.

0

Creo que es difícil juzgar la diferencia entre UTF-16, que es solo una secuencia de palabras de 16 bits, al objeto de cadena de Python.

Y si python se compila con la opción Unicode = UCS4, se comparará entre UTF-32 y la cadena de Python.

Por lo tanto, mejor considerar, se encuentran en diferentes categorías, aunque puede transformarse unos a otros.

5

Mirando el código fuente para CPython 3.1.5, en 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; 

Los caracteres se almacenan como una matriz de Py_UNICODE. En la mayoría de las plataformas, creo que Py_UNICODE es #define d como wchar_t.

23

La representación interna cambiará en Python 3.3 que implementa PEP 393. La nueva representación elegirá uno o varios de ascii, latin-1, utf-8, utf-16, utf-32, generalmente tratando de obtener una representación compacta.

Las conversiones implícitas en parejas sustitutas solo se realizarán al hablar con API heredadas (esas solo existen en Windows, donde wchar_t es de dos bytes); la cadena de Python se conservará. Aquí están los release notes.

+4

Me parece que PEP 393 dice que la representación interna es la más compacta (dada una cadena particular) de ASCII, Latin-1 (UCS1), UCS2 o UCS4. Es decir: específicamente NO utf-8/16/32. La razón: Python debe ser un tiempo constante para indexar en una cadena, por lo tanto, los caracteres deben ser de tamaño uniforme, que es el caso de UCS, pero no para las representaciones utf. – gwideman

+0

PEP 393 lo dice todo ... –

+0

Latin-1 es un superconjunto de ASCII, por lo que no hay ninguna razón para incluir ASCII como una de las opciones. Las opciones son (a) uniformemente de 8 bits, es decir, Latin-1, (b) uniformemente de 16 bits, es decir UCS2, o (c) uniformemente de 32 bits, es decir, UCS4 (que es lo mismo que UTF-32). Se excluyen notablemente UTF-8 y UTF-16, que no tienen un número uniforme de bits por punto de código – JoelFan

4

En Python 3.3 y superior, la representación interna de la cadena dependerá de la cadena, y puede ser cualquiera de ascii, latin-1, utf-8, utf-16, utf-32, según lo observado por Tobu y descrito en PEP 393.

Para las pitones anteriores, la representación interna depende de las marcas de compilación de Python. Python se puede construir con los valores de indicador --enable-unicode=ucs2 o --enable-unicode=ucs4. ucs2 compilaciones de hecho use UTF-16 as their internal representation, y ucs4 compilaciones usan UCS-4/UTF-32.

+1

Mi lectura de PEP393 es que la representación interna nunca es utf-8 ni ninguna otra codificación con un número incoherente de bytes por código. punto (símbolo), y que el conjunto correcto es: 'Latin-1',' UCS-2', o 'UCS-4'. No estoy seguro de tener este derecho. Leí que los únicos formularios utf-8 están en la entrada, o en algunos casos en la salida de la memoria caché. –

Cuestiones relacionadas