2015-03-17 3 views
5

In Python 2.7:Python gibt Länge von 2 für einzelne Unicode-Zeichenfolge

In [2]: utf8_str = '\xf0\x9f\x91\x8d' 
In [3]: print(utf8_str) 

In [4]: unicode_str = utf8_str.decode('utf-8') 
In [5]: print(unicode_str) 
    
In [6]: unicode_str 
Out[6]: u'\U0001f44d' 
In [7]: len(unicode_str) 
Out[7]: 2 

Da unicode_str enthält nur einen einzigen Unicode-Codepunkt (0x0001f44d), warum tut len(unicode_str) Rückkehr 2 statt 1?

Antwort

14

Ihr Python binäres wurde mit UCS-2-Unterstützung (a schmalen build) und intern etwas außerhalb des BMP (Basic Multilingual Plane) kompiliert wird, ein surrogate pair dargestellt werden.

Das bedeutet, dass solche Codepunkte bei der Abfrage der Länge als 2 Zeichen angezeigt werden.

Sie werden Ihre Python binär verwenden UCS-4 statt, wenn diese Angelegenheiten neu kompilieren müssen (./configure --enable-unicode=ucs4 wird es ermöglichen), oder ein Upgrade auf Python 3.3 oder neuer, wo Python's Unicode support was overhauled ein variabler Breite Unicode-Typ zu verwenden, die zwischen den Schaltern ASCII, UCS-2 und UCS-4 wie von den enthaltenen Codepunkten gefordert.

In Python-Versionen 2.7 und 3.0 - 3.2 können Sie feststellen, welche Art von Build Sie haben, indem Sie die sys.maxunicode value; Es wird 2^16-1 == 65535 == 0xFFFF für einen schmalen UCS-2-Build, 1114111 == 0x10FFFF für einen breiten UCS-4-Build sein. In Python 3.3 und oben ist es immer auf 1114111.

Demo:

# Narrow build 
$ bin/python -c 'import sys; print sys.maxunicode, len(u"\U0001f44d"), list(u"\U0001f44d")' 
65535 2 [u'\ud83d', u'\udc4d'] 
# Wide build 
$ python -c 'import sys; print sys.maxunicode, len(u"\U0001f44d"), list(u"\U0001f44d")' 
1114111 1 [u'\U0001f44d'] 
+0

Sie 'sys.maxunicode' auf Python 3 verwenden. Es ist impliziert, aber es ist es wert, explizit darauf hingewiesen, dass 'len (u 'U0001f44d') == 1 'auf Python 3.3 + (oder eine breite Python 2 Build) – jfs

+0

@ JFSebastian: sicher, aber wie von 3.3 ist es eine Konstante dort, da Python 3.3 und höher transparent zwischen ASCII, UCS-2 und einem UCS-4-Speicher für Strings nach Bedarf wechselt. Und du willst Python <3.3 sowieso nicht benutzen. –

+0

In Python 3.3+ gibt es keine enge/weite Unterscheidung (die interne Repräsentation wird nicht angezeigt - es ist Ihnen egal, was Python intern verwendet). Der Punkt, an dem Sie 'sys.maxunicode' verwenden können, unabhängig von der Version. – jfs

Verwandte Themen