str、bytes和bytearray简介
str是字符数据,bytes和bytearray是字节数据。它们都是序列,可以进行迭代遍历。str和bytes是不可变序列,bytearray是可变序列,可以原处修改字节。
str
str将各个字符组合在一起,以一种不可变序列进行存储。但是在底层它还是一个个的二进制数,是由一个个的字节组成的(也就是byte),只不过python根据指定的字符集编码"强行"将字节序列显示为字符。
python 3.x中默认str是unicode格式编码的,例如UTF-8字符集。
unicode编码的str,意味着能够直接存储除ascii码外的很多字符,比如中文,比如欧洲的重音符号。还意味着可以将一个unicode字符存储为多个字节,并将连续多个的字节翻译成单个对应的字符。
>>> a = "我"
>>> a
'我'
>>> ord(a)
25105
>>> a.encode()
b'\xe6\x88\x91'
bytes
bytes是不可变的二进制格式字节数据(注意,是字节不是字符),以整数方式表示。例如对于ascii范围内的字符"a",它存储为97。
要构造bytes类型的数据,方法之一是在字符串前面加上b或B前缀。
>>> B = b"abcd"
>>> [i for i in B]
[97, 98, 99, 100]
>>> B[0] = "A"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment
bytearray
bytearray是可变的二进制数据(byte)。
要构造bytearray对象,方法之一是将bytes数据作为bytearray()方法的参数,或者将str数据和编码作为参数。
>>> S = b"abcd"
>>> BA = bytearray(S)
>>> [ i for i in BA ]
[97, 98, 99, 100]
>>> BA[0] = 65
>>> BA
bytearray(b'Abcd')
unicode字符
单字节的字符(8bit位,共256个字符,ascii只用到了7个字节)能表示出来的字符毕竟有限,例如它没法表示出中文字符。
所以,各国设计了各种多字节的字符编码来表达自己国家的文字,底层仍然使用二进制数存储,然后通过设计好的编码表将二进制数转换成各种字符。比如中国有GBK的各种编码,还有全球通用的编码类型unicode、utf-8、utf-16等。
无论什么编码,内部都包含ascii编码(也有例外,比如utf-16),它只需单个字节。也就是说,ascii编码是任何其它编码表的子集。但有些编码表强制规定每个字符占多少个字节(比如unicode固定为2个字节),有些编码表动态决定每个字符占多少个字节(比如utf-8是变长的,可能占用1-4个字节空间,存储字母为1个字节,存储中文字符为3个字节)。
关于unicode和utf-X格式的编码关系,粗略地可以认为utf-X是unicode格式的一种特殊类型。实际上在存储utf数据时,内部会自动在Unicode和utf之间进行转换。
要构建Unicode类型,只需加上u或U前缀。
>>> U = u"我爱你"
>>> B = bytes(U,"utf-8")
>>> B
b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'
>>> BA = bytearray(U,"utf-8")
>>> BA
bytearray(b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0')