Unicode编码系统为表达任意语言的任意字符设计,使用4字节存储,每一个数字表明惟一的至少在某种语言中使用的字符。被几种语言共用的字符一般使用相同的数字编码,除非存在一个在理的语源学理由不容许这样作。python
Unicode编码模式有:算法
(1)、UTF-32:4字节存储,第N个字符从第4×Nth个字节开始。windows
(2)、UTF-16:2字节存储,将0-65535范围内的字符编码成2个字节,超过的须要一些技巧来实现。数组
使用UTF-32和UTF-16须要定义一个“字节顺序标记”,它是一个特殊的非打印字符,能够把它包含在文档的开头来指示你所使用的字节顺序。好比UTF-16,字节顺序标记为U+FEFF,若是收到的是FFFE开头的UTF-16编码文件,则字节顺序是单向的,以FEFF开头,则肯定字节顺序反向了。函数
(3)、UTF-8:变长编码系统。对于ASCII仅用1字节,每一个字符使用不一样数量的字节编码。因为位操做的天性使然,使用UTF-8再也不存在字节顺序的问题。一份以UTF-8编码的文档在不一样的计算机之间是同样的比特流。编码
二、概述spa
在Python 3,全部的字符串都是使用Unicode编码的字符序列。再也不存在以UTF-8或者CP-1252编码的状况。也就是说,“这个字符串是以utf-8编码的吗?再也不是一个有效问题。”utf-8是一种将字符编码成字节序列的方式。若是须要将字符串转换成特定编码的字节序列,Python 3能够为你作到。若是须要将一个字节序列转换成字符串,Python 3也能为你作到。字节即字节,并不是字符。字符在计算机内只是一种抽象。字符串则是一种抽象的序列。
设计
>>> s = '深刻 Python' ① >>> len(s) ② 9 >>> s[0] ③ '深' >>> s + ' 3' ④ '深刻 Python 3'
三、格式化字符串code
>>> username = 'mark' >>> password = 'PapayaWhip' ① >>> "{0}'s password is {1}".format(username, password) ② "mark's password is PapayaWhip" ① 不,PapayaWhip真的不是个人密码。 ② 这里包含了不少知识。首先,这里使用了一个字符串字面值的方法调用。字符串也是对象,对象则有其方法。其次,整个表达式返回一个字符串。最后,{0}和{1} 叫作替换字段(replacement field),他们会被传递给format()方法的参数替换。
复合字段名:orm
>>> import humansize >>> si_suffixes = humansize.SUFFIXES[1000] ① >>> si_suffixes ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] >>> '1000{0[0]} = 1{0[1]}'.format(si_suffixes) ② '1000KB = 1MB'
>>> import humansize >>> import sys >>> '1MB = 1000{0.modules[humansize].SUFFIXES[1000][0]}'.format(sys) '1MB = 1000KB'
ys.modules
是一个保存当前Python实例中全部已经导入模块的字典。模块的名字做为字典的键;模块自身则是键所对应的值。在实际的Python代码中,字典sys.modules
的键是字符串类型的;为了引用它们,咱们须要在模块名周围放上引号(好比 'humansize'
)。可是在使用替换域的时候,咱们在省略了字典的键名周围的引号(好比 humansize
)。在此,咱们引用PEP 3101:字符串格式化高级用法,“解析键名的规则很是简单。若是名字以数字开头,则它被看成数字使用,其余状况则被认为是字符串。”
>>> '{0:.1f} {1}'.format(698.24, 'GB') '698.2 GB'这里:表示格式说明符的开始,.1表示四舍五入到小数点后1位,f表示浮点数。
四、其余字符串经常使用方法
>>> s = '''Finished files are the re- ① ... sult of years of scientif- ... ic study combined with the ... experience of years.''' >>> s.splitlines() ② ['Finished files are the re-', 'sult of years of scientif-', 'ic study combined with the', 'experience of years.'] >>> print(s.lower()) ③ finished files are the re- sult of years of scientif- ic study combined with the experience of years. >>> s.lower().count('f') ④ 6
>>> query = 'user=pilgrim&database=master&password=PapayaWhip' >>> a_list = query.split('&') ① >>> a_list ['user=pilgrim', 'database=master', 'password=PapayaWhip'] >>> a_list_of_lists = [v.split('=', 1) for v in a_list] ② >>> a_list_of_lists [['user', 'pilgrim'], ['database', 'master'], ['password', 'PapayaWhip']] >>> a_dict = dict(a_list_of_lists) ③ >>> a_dict {'password': 'PapayaWhip', 'user': 'pilgrim', 'database': 'master'}
>>> a_string = 'My alphabet starts where your alphabet ends.' >>> a_string[3:11] ① 'alphabet' >>> a_string[3:-3] ② 'alphabet starts where your alphabet en' >>> a_string[0:2] ③ 'My' >>> a_string[:18] ④ 'My alphabet starts' >>> a_string[18:] ⑤ ' where your alphabet ends.'
五、STRING vs. BYTES
字节即字节;字符是一种抽象。一个不可变(immutable)的Unicode编码的字符序列叫作string。一串由0到255之间的数字组成的序列叫作bytes对象。
>>> by = b'abcd\x65' ① >>> by b'abcde' >>> type(by) ② <class 'bytes'> >>> len(by) ③ 5 >>> by += b'\xff' ④ >>> by b'abcde\xff' >>> len(by) ⑤ 6 >>> by[0] ⑥ 97 >>> by[0] = 102 ⑦ Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'bytes' object does not support item assignment ① 使用“byte字面值”语法b''来定义bytes对象。byte字面值里的每一个字节能够是ascii字符或者是从\x00到\xff编码了的16进制数。 ② bytes对象的类型是bytes。 ③ 跟列表和字符串同样,咱们能够经过内置函数len()来得到bytes对象的长度。 ④ 使用+操做符能够链接bytes对象。操做的结果是一个新的bytes对象。 ⑤ 链接5个字节的和1个字节的bytes对象会返回一个6字节的bytes对象。 ⑥ 一如列表和字符串,可使用下标记号来获取bytes对象中的单个字节。对字符串作这种操做得到的元素仍为字符串,而对bytes对象作这种操做的返回值则为整数。确切地说,是0–255之间的整数。 ⑦ bytes对象是不可变的;咱们不能够给单个字节赋上新值。若是须要改变某个字节,能够组合使用字符串的切片和链接操做(效果跟字符串是同样的),或者咱们也能够将bytes对象转换为bytearray对象。
>>> by = b'abcd\x65' >>> barr = bytearray(by) ① >>> barr bytearray(b'abcde') >>> len(barr) ② 5 >>> barr[0] = 102 ③ >>> barr bytearray(b'fbcde') ① 使用内置函数bytearray()来完成从bytes对象到可变的bytearray对象的转换。 ② 全部对bytes对象的操做也能够用在bytearray对象上。 ③ 有一点不一样的就是,咱们可使用下标标记给bytearray对象的某个字节赋值。而且,这个值必须是0–255之间的一个整数。
>>> by = b'd' >>> s = 'abcde' >>> by + s ① Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't concat bytes to str >>> s.count(by) ② Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't convert 'bytes' object to str implicitly >>> s.count(by.decode('ascii')) ③ 1 ① 不能链接bytes对象和字符串。他们两种不一样的数据类型。 ② 也不容许针对字符串中bytes对象的出现次数进行计数,由于串里面根本没有bytes。字符串是一系列的字符序列。也许你是想要先把这些字节序列经过某种编码方式进行解码得到字符串,而后对该字符串进行计数?能够,可是须要显式地指明它。Python 3不会隐含地将bytes转换成字符串,或者进行相反的操做。 ③ 好巧啊…这一行代码恰好给咱们演示了使用特定编码方式将bytes对象转换成字符串后该串的出现次数。 因此,这就是字符串与字节数组之间的联系了:bytes对象有一个decode()方法,它使用某种字符编码做为参数,而后依照这种编码方式将bytes对象转换为字符串,对应地,字符串有一个encode()方法,它也使用某种字符编码做为参数,而后依照它将串转换为bytes对象
>>> a_string = '深刻 Python' ① >>> len(a_string) 9 >>> by = a_string.encode('utf-8') ② >>> by b'\xe6\xb7\xb1\xe5\x85\xa5 Python' >>> len(by) 13 >>> by = a_string.encode('gb18030') ③ >>> by b'\xc9\xee\xc8\xeb Python' >>> len(by) 11 >>> by = a_string.encode('big5') ④ >>> by b'\xb2`\xa4J Python' >>> len(by) 11 >>> roundtrip = by.decode('big5') ⑤ >>> roundtrip '深刻 Python' >>> a_string == roundtrip True ① a_string是一个字符串。它有9个字符。 ② by是一个bytes对象。它有13个字节。它是经过a_string使用utf-8编码而获得的一串字节序列。 ③ by仍是一个bytes对象。它有11个字节。它是经过a_string使用GB18030编码而获得的一串字节序列。 ④ 此时的by仍旧是一个bytes对象,由11个字节组成。它又是一种彻底不一样的字节序列,咱们经过对a_string使用Big5编码获得。 ⑤ roundtrip是一个字符串,共有9个字符。它是经过对by使用Big5解码算法获得的一个字符序列。而且,从执行结果能够看出,roundtrip与a_string是彻底同样的。
六、能够指定python源码的编码方式
Python3默认采用UTF-8编码,而Python2采用ASCII
能够每一个文件的第一行
# -*- coding: windows-1252 -*-或者
#!/usr/bin/python3 # -*- coding: windows-1252 -*-