Python食谱-1.21.Unicode字符串和普通字符串的互换
| 原文作者: | David Ascher, Paul Prescod |
|---|---|
| 中文翻译: | Tony (digitalsatori) |
问题
如何处理超出ASCII码字符集的文本数据?
解决方法
Unicode字符串可以按照指定的编码方式转换为普通字符串:
unicodestring = u"Hello world"
# 将Unicode对象转换为字符串对象: "encode"
utf8string = unicodestring.encode("utf-8")
asciistring = unicodestring.encode("ascii")
isostring = unicodestring.encode("ISO-8859-1")
utf16string = unicodestring.encode("utf-16")
# 将普通字符串对象转换为Unicode对象: "decode"
plainstring1 = unicode(utf8string, "utf-8")
plainstring2 = unicode(asciistring, "ascii")
plainstring3 = unicode(isostring, "ISO-8859-1")
plainstring4 = unicode(utf16string, "utf-16")
assert plainstring1 == plainstring2 == plainstring3 == plainstring4
讨论
如果需要处理非ASCII字符所组成的文本,就要学习Unicode的相关知识。比如,什么是Unicode?它是如何工作的?Python中如何使用它?在 Python食谱1.20 中,我们学习了Unicode的基本要点,本配方将进一步扩展这个话题。
我们不必了解Unicode的所有知识来处理现实世界中的问题,但是一些必要的基本知识是不可缺少的。首先我们要了解字节和字符的区别。在较早的时候,以ASCII码为中心的语言和环境里,字节和字符在概念上是相同的。一个字节可以存储256个值,因此在这样的环境中可以处理的字符不超过256个。与之相对,Unicode则拥有成千上万个字符,这意味着Unicode字符是无法用一个字节来表示;也因此需要你将字符和字节从此区分开来。
Python的标准字符串对象实际上是字节码字符串(bytestrings),而一个Python 的字符,即长度为一的字符串,就是一个字节。标准字符串类型实例的另外称呼方法'有8位字符串'或'普通字符串'。在本配方中我们称之为'字节码字符串实例',以表示其是以字节为主导的。
Python的Unicode字符是一个抽象的对象,其大小足以表示任何字符,在Python中用长整数表示。我们不必担心其内部表示方式。只有当其被发送到那些字节码主导的函数,比如文件对象的 write 方法,或者network socket对象的 send 方法时,我们要考虑其表示方式。这时需要决定如何将这些字符以字节方式表示。从Unicode转换为字节码字符串的过程称为字符串的编码。同样的,当要从文件,socket 或其它的字节主导的对象中加载Unicode字符串,我们需要将字符串从字节解码为字符。将Unicode对象转换为字节码字符串的方式有很多,它们都被称为编码(encoding)。由于众多历史,政治,技术上的原因,没有一个四海皆准的编码方式。每一个编码方式都有一个大小写不敏感的名字,这个名字往往要作为参数传递给 encode 和 decode 方法。以下是一些你需要知道的编码方式:
UTF-8编码可以处理所有的Unicode字符,同时它也能保持对ASCII的向后兼容。因此一个纯ASCII编码的文件也可被当作UTF-8编码文件,或者一个只使用ASCII码字符的UTF-8编码的文件,与同样字符的ASCII码编码文件是完全一样的。这个特性使UTF-8有良好的向后兼容性,特别是对某些旧的Unix工具程序来说非常方便。UTF-8是目前Unix上的最主要的编码方式,它也是XML文档的默认编码方式。UTF-8的主要弱点是对亚洲语言文本,效率偏低。
UTF-16编码为微软操作系统和Java环境所采纳。它对西方语言文字,效率偏低,但对亚洲语言文字,效率要高些。UTF-16有时也被称为UCS-2。
ISO-8859系列编码是ASCII编码的超集,能处理256和不同的字符。这些编码方式不能支持全部的Unicode字符;它们只支持特定的几种语言,或语言族。ISO-8859-1,又被称为"Latin-1" 包含了大多数的西欧和非洲的语言,不包括阿拉伯语言。ISO-8859-2, 也称为 'Latin-2' 包含许多东欧语言,比如保加利亚语和波兰语。 ISO-8859-15, 在当今欧洲非常流行,它基本上与 ISO-8859-1相同,当多了一个欧元符号。
如果希望对所有的Unicode字符编码,那你可能应该选择UTF-8。在以下情况中,要求我们使用相应指定的编码:当需要处理由其它程序或输入设备等创建的文本,或者创建符合下游程序,输出设备的编码的文本时。在 Python食谱1.22 中将学习通过程序的标准输出流对下游程序或设备发送文本时的编码处理。
参见
Unicode是一个很大的话题,推荐阅读《Unicode: A Primer》,作者 Tony Graham (Hungry Minds, Inc 发行),详情请见 http://www.menteith.com/wiki/unicode/primer/; 还有一篇 Joel Spolsky 写的短小精湛的文章, 名为 "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses)!," 位于: http://www.joelonsoftware.com/articles/Unicode.html. 请参考Python库参考手册和Python in a Nutshell中关于内置函数str, unicode类型 ,以及unidata模块和codecs的内容。另外,请参考 Python食谱1.20 和 Python食谱1.22 的内容。













