您好,登錄后才能下訂單哦!
這篇文章主要介紹“Python之string編碼問題怎么解決”,在日常操作中,相信很多人在Python之string編碼問題怎么解決問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Python之string編碼問題怎么解決”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
通常我們所說的編碼一般為簡(jiǎn)稱, 其實(shí)在平常的應(yīng)用過程,編碼一般包括 編碼和解碼,如在編碼前指定 字符集UTF-8
, 那么解碼時(shí)也必須為UTF-8
,否則會(huì)出現(xiàn)所謂的 亂碼
字符集類似于中文,英文,是一個(gè)規(guī)則集合的抽象概念,其規(guī)定了某個(gè)文字對(duì)應(yīng)的二進(jìn)制數(shù)字存放方式,即為編碼過程,或者二進(jìn)制數(shù)字對(duì)應(yīng)的文字,即為解碼過程!
字符集包括如下:
1.字庫(kù)表
字庫(kù)表是一個(gè)相當(dāng)于所有可讀或者可顯示字符的數(shù)據(jù)庫(kù),字庫(kù)表決定了整個(gè)字符集能夠展現(xiàn)表示的所有字符的范圍
2.編碼字符集(通常簡(jiǎn)稱 字符集)
編碼字符集,用一個(gè)編碼值code point(二進(jìn)制代碼)來表示一個(gè)字符(即該字符在字庫(kù)表中的位置)
3.字符編碼
字符編碼,是編碼字符集和實(shí)際存儲(chǔ)數(shù)值之間的轉(zhuǎn)換關(guān)系;
字符,是根據(jù)字符編碼方案轉(zhuǎn)換為一個(gè)二進(jìn)制數(shù)值存儲(chǔ)在計(jì)算機(jī)中的
一個(gè)范例
下面以一個(gè)實(shí)例解釋下編解碼的過程
字符編碼: UTF-8
字符串:中國(guó)
Python版本:2.7
說明:
1.編碼轉(zhuǎn)換方式
str_unicode為中間碼。
即對(duì)應(yīng)編碼字符集 在字庫(kù)表中有唯一id代表一個(gè)字符, 理論上 unicode即可以映射表示所有字符,但是為了壓縮存儲(chǔ)的位數(shù),發(fā)展出了 utf-8、utf-16等字符編碼,即在實(shí)際存儲(chǔ)和字符展現(xiàn)之間又建立了一層映射,這層映射表示了 utf-8 到 unicode的方式,然后unicode又根據(jù)字庫(kù)表展現(xiàn)改字符。
即 unicode有 utf-8及utf-16等多種方式的字符編碼方案,GBK字符集 則只有一種字符編碼 EUC-CN, 而對(duì)于Ascii碼來說,本身即是編碼字符集又是字符編碼,
2.以一次Python代碼執(zhí)行為例, 解釋 字庫(kù)表、編碼字符集(字符集) 與 字符編碼的關(guān)系:
utf-8編碼如何規(guī)定的?
單字節(jié)的字符,字節(jié)的第一位設(shè)為0,對(duì)于英語(yǔ)文本,UTF-8碼只占用一個(gè)字節(jié),和ASCII碼完全相同;
n個(gè)字節(jié)的字符(n>1),第一個(gè)字節(jié)的前n位設(shè)為1,第n+1位設(shè)為0,后面字節(jié)的前兩位都設(shè)為10,這n個(gè)字節(jié)的其余空位填充該字符unicode碼,高位用0補(bǔ)足。
UTF-8編碼方式
----------------------
0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
utf-8和unicode的關(guān)系
utf 解釋為誒 Unicode TransferFormat 即 轉(zhuǎn)換Unicode。
unicode是一種字符編碼,規(guī)定了每個(gè)字符到數(shù)字的映射關(guān)系, 這個(gè)數(shù)字怎么存儲(chǔ)它沒有規(guī)定. 而如何存儲(chǔ)? 幾個(gè)字節(jié)表示? 這個(gè)是utf8等編碼方式來規(guī)定的。
有了unicode為什么還需要utf-8呢?
首先 unicode 規(guī)定了所有字符的二進(jìn)制編碼,并沒有規(guī)定如何存儲(chǔ)
如果我們以統(tǒng)一4個(gè)字節(jié)來存儲(chǔ)所有unicode的編碼字符,那就會(huì)在表示一個(gè)字節(jié)編碼的ascii部分嚴(yán)重浪費(fèi)存儲(chǔ)性能
另外因?yàn)榻y(tǒng)一4字節(jié)處理,那如果一個(gè)文件分片或者是一份缺失文件,那么此時(shí)該如何來判斷我們從頭讀取的 4字節(jié)是一個(gè)完整的字符呢?這就會(huì)造成很大的分析復(fù)雜度,可以說 無(wú)法分析, 這也是 utf-8等編碼的優(yōu)點(diǎn)即utf-8錯(cuò)誤編碼不會(huì)向后擴(kuò)散
綜合考慮 utf-8 是一種unicode 標(biāo)準(zhǔn)的存儲(chǔ)方案,改方案規(guī)定了如何存儲(chǔ)unicode字符,即看上面的utf-8的規(guī)定,大白話講就是 utf-8 可變長(zhǎng)編碼規(guī)定了 字符的起始位置,且極大可能節(jié)省存儲(chǔ)空間,總而言之很簡(jiǎn)單就是在無(wú)序中找到秩序
下列四種影響Python執(zhí)行的編碼方案,具體實(shí)例以最后所列案例為準(zhǔn)
獲取解釋器默認(rèn)編碼,Python3對(duì)應(yīng)的默認(rèn)編碼為 utf-8,Python2對(duì)應(yīng)的默認(rèn)編碼為ascii
import sys print(sys.getdefaultencoding())
Python2設(shè)置默認(rèn)編碼方式,Python3解釋器默認(rèn)utf-8所以去除該種設(shè)置方式
import sys reload(sys) sys.setdefaultencoding('utf-8')
解釋器編碼有什么用?
當(dāng)調(diào)用 decode() 和 encode() 進(jìn)行編碼轉(zhuǎn)換時(shí)候,如果未指定編碼格式,會(huì)調(diào)用解釋器默認(rèn)編碼進(jìn)行編碼轉(zhuǎn)換
若未指定編碼方式 而有中文出現(xiàn),此時(shí)會(huì)有報(bào)錯(cuò)產(chǎn)生
python源文件的編碼與解碼,我們寫的python程序從產(chǎn)生到執(zhí)行的過程如下(以Pycharm為例)
依次為
編輯器 決定源代碼的編碼格式(編輯器中設(shè)置)
pycharm 會(huì)根據(jù)文件開頭的編碼聲明進(jìn)行文件格式保存
此種聲明保存的文件,是utf-8編碼的
# coding: utf-8
此種聲明保存的文件,是gbk編碼的
# coding: gbk
同時(shí)也可以在setting中進(jìn)行設(shè)置
解釋器按照Ascii
或者聲明指定的方式解碼源代碼, 以下是 官方文檔給的解釋
Python will default to ASCII as standard encoding if no other encoding hints are given.
※: Python2中會(huì)按照編碼聲明對(duì)源代碼進(jìn)行解碼,如未指定 編碼聲明 則會(huì)以 Ascii進(jìn)行解碼,此時(shí)如果有中文會(huì)報(bào)錯(cuò)
※:Python3默認(rèn)以utf-8
進(jìn)行解碼
若未指定編碼聲明, 而源代碼中有中文
此時(shí)Python2 會(huì)以Ascii 來進(jìn)行源代碼的'解碼';Python3 會(huì)默認(rèn)以 utf-8 進(jìn)行源代碼的'解碼'。
若源文件編碼為utf-8
, 而編碼聲明 為gbk
這種情況會(huì)出錯(cuò),因?yàn)榇疟P中保存的格式時(shí) gbk 格式的而卻以 utf-8 來進(jìn)行解碼,則會(huì)出錯(cuò)。
UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence
注意1:Python3將源代碼讀取到內(nèi)存中的字符串編碼為 unicode
, 這樣的中間碼的方式,不會(huì)出現(xiàn)亂碼, Python2以文件頭聲明的方式將源代碼讀取到內(nèi)存中
注意2:Python2 在日常編程中一定注意 文件編碼 和 文件聲明要一致,如 文件編碼為 utf-8 則此時(shí)應(yīng)該如此聲明 # coding: utf-8
, 若此時(shí)用gbk
做聲明,則此時(shí)會(huì)亂碼,一編一解 要成對(duì)
結(jié)果輸出,控制臺(tái)輸出 或 日志文件
解釋器如何知道該文件的編碼格式?
# coding: utf-8
locale 模塊獲取 操作系統(tǒng)編碼
import locale print locale.getdefaultencoding()
以open()函數(shù)為例
open() 函數(shù)會(huì)調(diào)用 Python操作系統(tǒng)默認(rèn)編碼進(jìn)行 編解碼
# coding: utf-8 import sys; reload(sys); sys.setdefaultencoding('utf-8') str = '中國(guó)' # utf-8 bytes類型 str_unicode = str.decode() # unicode with open('demo.txt', 'w') as f: f.write(str) # 寫入bytes類型,則此時(shí)文件編碼為 utf-8 f.write(str_unicode) # 寫入 unicode,則此時(shí)會(huì)根據(jù) sys.getdefaultencoding() 來進(jìn)行文件編碼
linux 下 vim打開以 gbk方式寫入的文件會(huì)出現(xiàn)亂碼,因?yàn)榇藭r(shí)會(huì)調(diào)用操作系統(tǒng)的編碼方式進(jìn)行解碼
終端編碼 繼承自操作系統(tǒng)的編碼
print("你好".encode('utf-8')) >>> b'\xe4\xbd\xa0\xe5\xa5\xbd'
很容易看出 其中的 16進(jìn)制數(shù) e4bda0e5a5bd
對(duì)于字節(jié)流(bytes: 如utf-8字節(jié)流)來說表示字節(jié)數(shù)
對(duì)于unicode則表示字符數(shù)
Pycharm編碼設(shè)置
字符串變量級(jí)別編碼
腳本級(jí)別的編碼
py文件級(jí)別的編碼
顯示窗口的編碼
問題收集 python3 unicode字符轉(zhuǎn)中文
a = "\\u4ea7\\u54c1\\u72b6\\u6001" # 兩種方式 print(eval(f'u"{a}"')) print(a.encode().decode("unicode_escape"))
即 一個(gè)字符可以是一個(gè)中文漢字、一個(gè)英文字母、一個(gè)阿拉伯?dāng)?shù)字、一個(gè)標(biāo)點(diǎn)符號(hào)等 ??
如:Unicode、ASCII
到此,關(guān)于“Python之string編碼問題怎么解決”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。