字符編碼由來
由于計算機是美國人發(fā)明的,因此,最早只有127個字符被編碼到計算機里,也就是大小寫英文字母、數(shù)字和一些符號,這個編碼表被稱為ASCII編碼,比如大寫字母A的編碼是65,小寫字母z的編碼是122。
但是要處理中文顯然一個字節(jié)是不夠的,至少需要兩個字節(jié),而且還不能和ASCII編碼沖突,所以,中國制定了GB2312編碼,用來把中文編進去。
你可以想得到的是,全世界有上百種語言,日本把日文編到Shift_JIS里,韓國把韓文編到Euc-kr里,各國有各國的標準,就會不可避免地出現(xiàn)沖突,結(jié)果就是,在多語言混合的文本中,顯示出來會有亂碼。
因此,Unicode應(yīng)運而生。Unicode把所有語言都統(tǒng)一到一套編碼里,這樣就不會再有亂碼問題了。新的問題又出現(xiàn)了:如果統(tǒng)一成Unicode編碼,亂碼問題從此消失了。但是,如果你寫的文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不劃算。
本著節(jié)約的精神,又出現(xiàn)了把Unicode編碼轉(zhuǎn)化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據(jù)不同的數(shù)字大小編碼成1-6個字節(jié),常用的英文字母被編碼成1個字節(jié),漢字通常是3個字節(jié),只有很生僻的字符才會被編碼成4-6個字節(jié)。如果你要傳輸?shù)奈谋景罅坑⑽淖址?,用UTF-8編碼就能節(jié)省空間
Python的字符編碼
在最新的Python 3版本中,字符串是以Unicode編碼的,也就是說,Python的字符串支持多語言。
對于單個字符的編碼,Python提供了ord()函數(shù)獲取字符的整數(shù)表示,chr()函數(shù)把編碼轉(zhuǎn)換為對應(yīng)的字符
????????ord('A')? →? 65
????????chr(66) →? 'B'
同時,輸入字符串時,可通過\u轉(zhuǎn)置字符的16進制編碼,例如
????????'\u4f60\u597d' → 你好
16進制編碼可以用電腦自帶的計算器進行轉(zhuǎn)換。
類型轉(zhuǎn)換(str和bytes轉(zhuǎn)換)
類型轉(zhuǎn)換采用encode方法(s轉(zhuǎn)b)和decode方法(b轉(zhuǎn)s)。
Python的字符串類型是str ,而網(wǎng)絡(luò)傳輸常用bytes類型。轉(zhuǎn)換可以使用encode()方法將str編碼為指定的bytes類型,例如將str類型的字符ABC轉(zhuǎn)換為utf-8類型的bytes類型:
????????'ABC'.encode('utf-8')? ? →? b'ABC'
如果希望將網(wǎng)絡(luò)或磁盤讀取的字節(jié)流(bytes格式)轉(zhuǎn)換為字符(str類型),則需要對bytes類型數(shù)據(jù)使用decode()方法,例如,bytes類型的數(shù)據(jù)和str類型數(shù)據(jù)相互轉(zhuǎn)換示意:
>>> x='你好'
#設(shè)x為str類型:你好
>>> y='ABC'
#設(shè)y為str類型:ABC
>>> a=x.encode('utf-8')
#a為x轉(zhuǎn)換為bytes類型數(shù)據(jù)的值,通過utf-8編碼
>>> b=y.encode('utf-8')
#b為y轉(zhuǎn)換為bytes類型數(shù)據(jù)的值,通過utf-8編碼
>>> print(a)
#輸出a的值
b'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print(b)
#輸出b的值
b'ABC'
>>> d=a.decode('utf-8')
#將a轉(zhuǎn)換回str類型,通過utf-8編碼,值設(shè)為d
>>> e=b.decode('utf-8')
#將b轉(zhuǎn)換回str類型,通過utf-8編碼,值設(shè)為e
>>> print(d)
#輸出d
你好
>>> print(e)
#輸出e
ABC
如果bytes中包含無法解碼的字節(jié),decode()方法會報錯。
如果bytes中只有一小部分無效的字節(jié),可以傳入errors='ignore'忽略錯誤的字節(jié),該參數(shù)默認為errors='strict'嚴格模式,示意:
????????b=b'\xe4\xbd\xa0\xe5\xa5\xbd\xaaaaaaaaa'
????????>>> print(b.decode('utf-8'))
????????Traceback (most recent call last):
????????? File "<pyshell#77>", line 1, in <module>
? ????????? print(b.decode('utf-8'))
????????UnicodeDecodeError: 'utf-8' codec can't decode byte 0xaa in position 6: invalid start byte
????????>>> print(b.decode('utf-8',errors='ignore'))
????????你好aaaaaaa
要計算str包含多少個字符,可以用len()函數(shù)。
????????len('馕'.encode('utf-8'))
????????3
????????len(b'A')
????????1
????????len('馕')
????????1
每個英文占1個字節(jié),中文編碼后占3個字符,而編碼前占1個字符。
編碼聲明
由于Python源代碼也是一個文本文件,所以,當你的源代碼中包含中文的時候,在保存源代碼時,就需要務(wù)必指定保存為UTF-8編碼。當Python解釋器讀取源代碼時,為了讓它按UTF-8編碼讀取,我們通常在文件開頭寫上這兩行:
????????????????#!/usr/bin/env python3
????????????????# -*- coding: utf-8 -*-
第一行注釋是為了告訴Linux/OS X系統(tǒng),這是一個Python可執(zhí)行程序,Windows系統(tǒng)會忽略這個注釋;
第二行注釋是為了告訴Python解釋器,按照UTF-8編碼讀取源代碼,否則,你在源代碼中寫的中文輸出可能會有亂碼。
申明了UTF-8編碼并不意味著你的.py文件就是UTF-8編碼的,必須并且要確保文本編輯器正在使用UTF-8 without BOM編碼。
格式化字符串:%占位符
在Python中,以%作為格式化字符。
占位符:
????????占位符 ???????? 替換內(nèi)容
????????%d? ????????????? 整數(shù)
????????%f? ? ???????????? 浮點數(shù)
????????%s ???????????? 字符串
????????%x ???????????? 十六進制整數(shù)
其中,格式化整數(shù)和浮點數(shù)還可以指定是否補0和整數(shù)與小數(shù)的位數(shù)
????????例1:
????????a='小明'
????????b='我的空間'
????????c=12
????????w='%s ,您好,歡迎光臨%s,您是第%d個訪客' % (a,b,c)
????????print(w)
????????輸出:小明 ,您好,歡迎光臨我的空間,您是第12個訪客
例2:
????????print('%2d-%02d' % (3, 1))
????????print('%.2f' % 3.1415926)
????????>>> print(('the number is %.2f')%(12.1))
????????the number is 12.10
????????>>> print(('the number is %.5f')%(12.1))
????????the number is 12.10000
????????格式:% + 點 + 位數(shù) + f? 【指定浮點數(shù)小數(shù)點保留位數(shù)】
????????格式:% + 0 + 位數(shù) + d 【指定最小位數(shù),不足在前邊補零,如內(nèi)容超過位數(shù)則不做處理,如替代內(nèi)容為小數(shù),向下取整】
????????格式:% + 位數(shù) + d 【指定最小位數(shù),不足在前邊補空格,如內(nèi)容超過位數(shù)則不做處理,如替代內(nèi)容為小數(shù),向下取整】
格式化字符串:format()
另一種格式化字符串的方法是使用字符串的format()方法,它會用傳入的參數(shù)依次替換字符串內(nèi)的占位符{0}、{1}……,參數(shù)一般從0開始,但允許指定順序或指定參數(shù):
例1:
????????>>> 'hello,{0},歡迎{1}的你,來到{2}!'.format('王','智慧','新空間')
????????'hello,王,歡迎智慧的你,來到新空間!'
例2:
????????>>> 'hello,{0},歡迎{3}的你,來到{5}!'.format('王','智慧','機智','新空間','新世紀','零度空間')
????????'hello,王,歡迎新空間的你,來到零度空間!'