Python / Django 中 Unicode 与 UTF-8 的混淆?
我在Django教程中看到了一段话,感觉有点困惑:
Django模型有一个默认的str()方法,它会调用unicode(),并把结果转换成UTF-8字节串。这意味着,unicode(p)会返回一个Unicode字符串,而str(p)会返回一个普通字符串,字符会以UTF-8格式编码。
现在我有点糊涂,因为据我所知,Unicode并不是某种特定的表示方式,那么在Python中“Unicode字符串”是什么意思呢?这是不是指UCS-2?我在网上搜索时发现了这个“Python Unicode教程”,里面明确说:
Unicode是一种两字节编码,涵盖了世界上所有常见的书写系统。
这显然是错误的,还是说其实没错?我曾经因为字符集和编码的问题感到困惑,但在这里我很确定我读到的文档是搞错了。有没有人知道在Python中,当我得到一个“Unicode字符串”时到底发生了什么?
5 个回答
Python把Unicode字符存储为UTF-16格式。使用str()函数时,它会返回这个UTF-16字符串的UTF-8表示形式。
同时,我做了一些深入的研究,想确认一下Python内部是怎么表示字符的,以及它的限制是什么。"Python中的Unicode真相"这篇文章非常好,里面直接引用了Python开发者的说法。显然,Python内部的字符表示要么是UCS-2,要么是UCS-4,这取决于编译时的设置。所以Jon,虽然这不是UTF-16,但你的回答让我找到了正确的方向,感谢你。
在Python中,什么是“Unicode字符串”?这是否意味着UCS-2?
在Python中,Unicode字符串的存储方式有两种:一种是UCS-2(固定长度的16位表示,几乎和UTF-16一样),另一种是UCS-4/UTF-32(固定长度的32位表示)。这其实是在编译时就决定的;在Windows系统上,它总是使用UTF-16,而很多Linux版本则会选择UTF-32(也叫“宽模式”)。
一般来说,你不需要太在意这些细节:你在字符串中看到的Unicode字符都是单独的元素,你根本不知道它们是用两个字节还是四个字节存储的。如果你在使用UTF-16版本的Python,而需要处理一些超出基本多语言平面的字符,那就说明你可能做错了,但这种情况很少见,真正需要这些额外字符的用户应该使用宽版本的Python。
这完全错了吗,还是有道理的?
是的,这确实是错的。公平地说,我觉得那个教程有点过时;它可能是在宽Unicode字符串出现之前写的,甚至可能在Unicode 3.1(引入了基本多语言平面之外的字符的版本)之前。
还有一个让人困惑的地方是,Windows习惯上把“Unicode”这个词特指NT内部使用的UTF-16LE编码。来自微软的人可能会经常沿用这种有点误导的说法。