日常小结-python2.x和python3.x之间关于String的区别

来源:互联网 发布:网络hk什么意思 编辑:程序博客网 时间:2024/06/07 02:07

本文内容主要来自于GTK+3 教程4How to Deal With Strings 我觉得内容写的挺好的,这里总结一下。

Unicode 及UTF-8

首先字符串可以看成是一串字符的表示,每个字符都可以用一串编码表示,全部的编码范围在0到0X10FFFF之间表示。这也就是所谓的Unicode。
Unicode是一种概念。这个概念是为了将全世界范围内每个字符都采用统一的规则来用唯一的数字来表示。Unicode诞生之前,ASCII码是广泛采用的编码方法。诞生ASCII所能表示的范围太少,于是就产生了各类的编码方式,不同编码方式带来了各种杂乱的问题,Unicode的诞生就是为了解决这个问题。Unicode并不是一种代码而是一种映射的概念(也就是所谓的字符集),并不是能直接传输的代码,也更不可能规定计算机该如何储存它。
如果想要传输Unicode则必须将其编码成为一组byte才行。而实现Unicode的最常见的编码方式就是所谓的UTF-8、UTF-16等。Unicode和UTF-8之间的区别,举个栗子就好像11这个数字可以用十进制11表示也可用十六进制B来表示一样,当然这样说也许并不恰当,因为11在计算机储存的时候一样的,不同进制只是对人来说看起来好像有点不一样,而Unicode和UTF-8、UTF-16却正好反过来,人看起是一样的东西但是在计算机看来却不一样。当然有人也许争论可以直接将Unicode直接按照二进制byte传输,确实是可以这样的,但是通常没有人这样做,因为太浪费空间了,而且也没有明显的好处。

UTF-8

关于UTF-8这里不介绍具体的编码方式仅仅讨论一些特性。

  • 首先ASCII字符表示的UTF-8都是一样的,都是用一个字符,而所有其他字符都是至少需要2个字符。
  • UTF-8是变长的1-4个字节。
  • 因为是变长的。所以无法根据Unicode或者UTF-8互相估计长度。
  • UTF-8是顺序无关的,UTF-16是有两种编码顺序。

Python2

对于python2由两种表示字符串的方式,一种是str,另一种是unicode。
unicode类型是表示标准的Unicode字符。
python中使用16位或者32位整数来表示,取决于python交互器如何编译。
使用unicode.encode()来将Unicode转换称为8-bit的字符串。

而str用byte表示的Unicode字符(编码后的字符)。
使用str.decode()将8-bit字符串解码成为unicode。

>>> unicode_string = u"Fu\u00dfb\u00e4lle">>> print unicode_stringFußbälle>>> type(unicode_string)<type 'unicode'>>>> unicode_string.encode("utf-8")'Fu\xc3\x9fb\xc3\xa4lle'
>>> utf8_string = " sind rund">>> unicode_string + utf8_stringu'Fu\xdfb\xe4lle sind rund'>>> utf8_string = " k\xc3\xb6nnten rund sein">>> print utf8_string könnten rund sein>>> unicode_string + utf8_stringTraceback (most recent call last):  File "<stdin>", line 1, in <module>UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2:ordinal not in range(128)

python2最大的问题是如果一个字符串只有128就可以表示的字符的话,那python允许你混淆unicode和str。如果由非ASCII编码的时候会出现UnicodeDecodeError。

由于在GTK里面说明的。这里说明依稀GTK里面的string使用。
GTK使用UTF-8编码所有的文本。所有方法都会返回str,当然正常情况下也应该传入str。
假如你不慎传入了Unicode方法,GTK会帮你自动编码成str。如果你试图返回也返回的是str。典型的例子:

>>> from gi.repository import Gtk>> label = Gtk.Label()>> unicode_string = u"Fu\u00dfb\u00e4lle">> label.set_text(unicode_string)>> txt = label.get_text()>> type(txt), txt(<type 'str'>, 'Fu\xc3\x9fb\xc3\xa4lle')>> txt == unicode_string__main__:1: UnicodeWarning: Unicode equal comparison failed to convertboth arguments to Unicode - interpreting them as being unequalFalse>> txt = label.get_text().decode("utf-8")>> txt == unicode_string

Python3

python中只使用str类型作为字符串储存的Unicode实例,编码后的二进制文件使用bytes类型表示。str表示内容,bytes表示数据。使用str.encode()和bytes.decode()来互相转换。如果混用会导致TypeError错误。

>>> text = "Fu\u00dfb\u00e4lle">>> data = b" sind rund">>> text + dataTraceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: Can't convert 'bytes' object to str implicitly>>> text + data.decode("utf-8")'Fußbälle sind rund'>>> text.encode("utf-8") + datab'Fu\xc3\x9fb\xc3\xa4lle sind rund'

GTK+中python的表示:
简单的多了,只使用str来表示。

>> from gi.repository import Gtk>> label = Gtk.Label()>> text = "Fu\u00dfb\u00e4lle">> label.set_text(text)>> txt = label.get_text()>> type(txt), txt(<class 'str'>, 'Fußbälle')>> txt == textTrue
0 0