I was happy in my Python world knowing that I was doing everything in Unicode and encoding as UTF-8 when I needed to output something to a user. Then, one of my colleagues sent me the "The UTF-8 Everywhere' manifesto" (2012) and it confused me.
- The author of the article claims a number of times that UCS-2, the Unicode representation that Python uses is synonymous with UTF-16.
- He even goes as far as directly saying Python uses UTF-16 for internal string representation.
- The author also admits to being a Windows lover and developer and states that the way MS has handled character encodings over the years has led to that group being the most confused so maybe it is just his own confusion. I don't know...
Can somebody please explain what the state of UTF-16 vs Unicode is in Python? Are they synonymous and if not, in what way?
-
1Why are you concerned with Python's internal string representation? The point of that site is to convince developers to use UTF-8 in all of the code they write - and you're not developing Python internals, are you?Matt Ball– Matt Ball2012年10月26日 22:58:02 +00:00Commented Oct 26, 2012 at 22:58
-
1UCS-2 and UTF-16 are not the same. UCS-2 is obsolete as it doesn't encode all of the Unicode code points.Mark Ransom– Mark Ransom2012年10月26日 23:00:14 +00:00Commented Oct 26, 2012 at 23:00
-
1@MattBall SO is about developers sharing knowledge (and helping each other out). This is something that interests me. Do I need any more reason to ask this question?Endophage– Endophage2012年10月26日 23:08:23 +00:00Commented Oct 26, 2012 at 23:08
-
@MarkRansom if you'd like to post an answer including that and your point from your comment below, I'd happily give you an upvote.Endophage– Endophage2012年10月26日 23:16:09 +00:00Commented Oct 26, 2012 at 23:16
-
1Have you read The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)?user395760– user3957602012年10月26日 23:27:42 +00:00Commented Oct 26, 2012 at 23:27
1 Answer 1
The internal representation of a Unicode string in Python (versions from 2.2 up to 3.2) depends on whether Python was compiled in wide or narrow modes. Most Python builds are narrow (you can check with sys.maxunicode -- it is 65535 on narrow builds and 1114111 on wide builds).
With a wide build, strings are internally sequences of 4-byte wide characters, i.e. they use the UTF-32 encoding. All code points are exactly one wide-character in length.
With a narrow build, strings are internally sequences of 2-byte wide characters, using UTF-16. Characters beyond the BMP (code points U+10000 and above) are stored using the usual UTF-16 surrogate pairs:
>>> q = u'\U00010000'
>>> len(q)
2
>>> q[0]
u'\ud800'
>>> q[1]
u'\udc00'
>>> q
u'\U00010000'
Note that UTF-16 and UCS-2 are not the same. UCS-2 is a fixed-width encoding: every code point is encoded as 2 bytes. Consequently, UCS-2 cannot encode code points beyond the BMP. UTF-16 is a variable-width encoding; code points outside the BMP are encoded using a pair of characters, called a surrogate pair.
Note that this all changes in 3.3, with the implementation of PEP 393. Now, Unicode strings are represented using characters wide enough to hold the largest code point -- 8 bits for ASCII strings, 16 bits for BMP strings, and 32 bits otherwise. This does away with the wide/narrow divide and also helps reduce the memory usage when many ASCII-only strings are used.
7 Comments
Explore related questions
See similar questions with these tags.