小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Python:徹底搞懂Python的字符編碼

 昵稱(chēng)57214244 2018-10-07

前言:中文編碼問(wèn)題一直是程序員頭疼的問(wèn)題,而Python2中的字符編碼足矣令新手抓狂。本文將盡量用通俗的語(yǔ)言帶大家徹底的了解字符編碼以及Python2和3中的各種編碼問(wèn)題。

一、什么是字符編碼。

要徹底解決字符編碼的問(wèn)題就不能不去了解到底什么是字符編碼。計(jì)算機(jī)從本質(zhì)上來(lái)說(shuō)只認(rèn)識(shí)二進(jìn)制中的0和1,可以說(shuō)任何數(shù)據(jù)在計(jì)算機(jī)中實(shí)際的物理表現(xiàn)形式也就是0和1,如果你將硬盤(pán)拆開(kāi),你是看不到所謂的數(shù)字0和1的,你能看到的只是一塊光滑閃亮的磁盤(pán),如果你用足夠大的放大鏡你就能看到磁盤(pán)的表面有著無(wú)數(shù)的凹凸不平的元件,凹下去的代表0,突出的代表1,這就是計(jì)算機(jī)用來(lái)表現(xiàn)二進(jìn)制的方式。

1.ASCII

現(xiàn)在我們面臨了第一個(gè)問(wèn)題:如何讓人類(lèi)語(yǔ)言,比如英文被計(jì)算機(jī)理解?我們以英文為例,英文中有英文字母(大小寫(xiě))、標(biāo)點(diǎn)符號(hào)、特殊符號(hào)。如果我們將這些字母與符號(hào)給予固定的編號(hào),然后將這些編號(hào)轉(zhuǎn)變?yōu)槎M(jìn)制,那么計(jì)算機(jī)明顯就能夠正確讀取這些符號(hào),同時(shí)通過(guò)這些編號(hào),計(jì)算機(jī)也能夠?qū)⒍M(jìn)制轉(zhuǎn)化為編號(hào)對(duì)應(yīng)的字符再顯示給人類(lèi)去閱讀。由此產(chǎn)生了我們最熟知的ASCII碼。ASCII 碼使用指定的7 位或8 位二進(jìn)制數(shù)組合來(lái)表示128 或256 種可能的字符。這樣在大部分情況下,英文與二進(jìn)制的轉(zhuǎn)換就變得容易多了。

2.GB2312

然而,雖然計(jì)算機(jī)是美國(guó)人發(fā)明的,但是全世界的人都在使用計(jì)算機(jī)。現(xiàn)在出現(xiàn)了另一個(gè)問(wèn)題:如何讓中文被計(jì)算機(jī)理解?這下麻煩了,中文不像拉丁語(yǔ)系是由固定的字母排列組成的。ASCII 碼顯然沒(méi)辦法解決這個(gè)問(wèn)題,為了解決這個(gè)問(wèn)題中國(guó)國(guó)家標(biāo)準(zhǔn)總局1980年發(fā)布《信息交換用漢字編碼字符集》提出了GB2312編碼,用于解決漢字處理的問(wèn)題。1995年又頒布了《漢字編碼擴(kuò)展規(guī)范》(GBK)。GBK與GB 2312—1980國(guó)家標(biāo)準(zhǔn)所對(duì)應(yīng)的內(nèi)碼標(biāo)準(zhǔn)兼容,同時(shí)在字匯一級(jí)支持ISO/IEC10646—1和GB 13000—1的全部中、日、韓(CJK)漢字,共計(jì)20902字。這樣我們就解決了計(jì)算機(jī)處理漢字的問(wèn)題了。

3.Unicode

現(xiàn)在英文和中文問(wèn)題被解決了,但新的問(wèn)題又出現(xiàn)了。全球有那么多的國(guó)家不僅有英文、中文還有阿拉伯語(yǔ)、西班牙語(yǔ)、日語(yǔ)、韓語(yǔ)等等。難不成每種語(yǔ)言都做一種編碼?基于這種情況一種新的編碼誕生了:Unicode。Unicode又被稱(chēng)為統(tǒng)一碼、萬(wàn)國(guó)碼;它為每種語(yǔ)言中的每個(gè)字符設(shè)定了統(tǒng)一并且唯一的二進(jìn)制編碼,以滿(mǎn)足跨語(yǔ)言、跨平臺(tái)進(jìn)行文本轉(zhuǎn)換、處理的要求。Unicode支持歐洲、非洲、中東、亞洲(包括統(tǒng)一標(biāo)準(zhǔn)的東亞象形漢字和韓國(guó)表音文字)。這樣不管你使用的是英文或者中文,日語(yǔ)或者韓語(yǔ),在Unicode編碼中都有收錄,且對(duì)應(yīng)唯一的二進(jìn)制編碼。這樣大家都開(kāi)心了,只要大家都用Unicode編碼,那就不存在這些轉(zhuǎn)碼的問(wèn)題了,什么樣的字符都能夠解析了。

4.UTF-8

但是,由于Unicode收錄了更多的字符,可想而知它的解析效率相比ASCII碼和GB2312的速度要大大降低,而且由于Unicode通過(guò)增加一個(gè)高字節(jié)對(duì)ISO Latin-1字符集進(jìn)行擴(kuò)展,當(dāng)這些高字節(jié)位為0時(shí),低字節(jié)就是ISO Latin-1字符。對(duì)可以用ASCII表示的字符使用Unicode并不高效,因?yàn)閁nicode比ASCII占用大一倍的空間,而對(duì)ASCII來(lái)說(shuō)高字節(jié)的0對(duì)他毫無(wú)用處。為了解決這個(gè)問(wèn)題,就出現(xiàn)了一些中間格式的字符集,他們被稱(chēng)為通用轉(zhuǎn)換格式,即UTF(Unicode Transformation Format)。而我們最常用的UTF-8就是這些轉(zhuǎn)換格式中的一種。在這里我們不去研究UTF-8到底是如何提高效率的,你只需要知道他們之間的關(guān)系即可。

總結(jié):

**1.為了處理英文字符,產(chǎn)生了ASCII碼。
2.為了處理中文字符,產(chǎn)生了GB2312。
3.為了處理各國(guó)字符,產(chǎn)生了Unicode。
4.為了提高Unicode存儲(chǔ)和傳輸性能,產(chǎn)生了UTF-8,它是Unicode的一種實(shí)現(xiàn)形式。**

二、Python2中的字符編碼

1.Python2中默認(rèn)的字符編碼是ASCII碼,也就是說(shuō)Python在處理數(shù)據(jù)時(shí),只要數(shù)據(jù)沒(méi)有指定它的編碼類(lèi)型,Python默認(rèn)將其當(dāng)做ASCII碼來(lái)進(jìn)行處理。這個(gè)問(wèn)題最直接的表現(xiàn)在當(dāng)我們編寫(xiě)的python文件中包含有中文字符時(shí),在運(yùn)行時(shí)會(huì)提示出錯(cuò)。如圖:

這里寫(xiě)圖片描述

這里寫(xiě)圖片描述

這個(gè)問(wèn)題出現(xiàn)的原因是:Python2會(huì)將整個(gè)python腳本中的內(nèi)容當(dāng)做ASCII碼去處理,當(dāng)腳本中出現(xiàn)了中文字符,比如這里的“小明”,我們知道ASCII碼是不能夠處理中文字符的,所以出現(xiàn)了這個(gè)錯(cuò)誤。解決的辦法是:在文件頭部加入一行編碼聲明,如圖:

這里寫(xiě)圖片描述

這里寫(xiě)圖片描述

這樣,Python在處理這個(gè)腳本時(shí),會(huì)用UTF-8的編碼去處理整個(gè)腳本,就能夠正確的解析中文字符了。

2.Python2中字符串有str和unicode兩種類(lèi)型。

這里寫(xiě)圖片描述

上圖中展現(xiàn)出了Python2中字符串的兩種類(lèi)型:

name變量被賦予了一個(gè)字符串“小明”;

unicode_name是name變量的unicode格式,這里我們使用了decode()方法,我們會(huì)在后面的內(nèi)容中詳細(xì)講解;

兩者在終端中返回了不同的字節(jié)串,type返回了不同的數(shù)據(jù)類(lèi)型,但print打印出了相同的輸出。

這里我們注意到一個(gè)“字節(jié)串”的名稱(chēng),字節(jié)串是指該字符串在python中的標(biāo)準(zhǔn)形式,也就是說(shuō)無(wú)論一個(gè)字符串是什么樣的編碼,在python中都會(huì)有一串字節(jié)串來(lái)進(jìn)行表示。字節(jié)串是沒(méi)有編碼的,對(duì)應(yīng)的最終交給計(jì)算機(jī)處理的數(shù)據(jù)形式。

3.Python2中可以直接查看到unicode的字節(jié)串。

在上圖中,輸入unicode_name的返回值,是一個(gè)unicode字節(jié)串,我們能夠直接看到這個(gè)字節(jié)串。而在python3中,我們將不能直接看到unicode字節(jié)串,它會(huì)被顯示為中文的“小明”;因?yàn)閜ython3默認(rèn)使用unicode編碼,unicode字節(jié)串將被直接處理為中文顯示出來(lái)。

總結(jié):

**1.Python2中默認(rèn)的字符編碼是ASCII碼。
2.Python2中字符串有str和unicode兩種類(lèi)型。str有各種編碼的區(qū)別,unicode是沒(méi)有編碼的標(biāo)準(zhǔn)形式。
3.Python2中可以直接查看到unicode的字節(jié)串。**

三、decode()與encode()方法

前面我們說(shuō)了這么多都是為了這一節(jié)做鋪墊,現(xiàn)在我們開(kāi)始來(lái)處理Python2中的字符編碼問(wèn)題。我們首先要學(xué)習(xí)Python為我們提供的兩個(gè)轉(zhuǎn)換編碼的方法decode()與encode()。

***decode()方法將其他編碼字符轉(zhuǎn)化為Unicode編碼字符。
encode()方法將Unicode編碼字符轉(zhuǎn)化為其他編碼字符。*

話(huà)不多說(shuō),直接上圖:

這里寫(xiě)圖片描述

chardet模塊可以檢測(cè)字符串編碼,沒(méi)有該模塊的可以用pip install chardet安裝。

首先解釋一下為什么name=”小明” 這里的小明是一個(gè)utf-8編碼的字符。因?yàn)槲沂褂玫氖荱buntu14.04操作系統(tǒng),系統(tǒng)默認(rèn)的字符編碼就是UTF-8,所以當(dāng)我在終端將一個(gè)中文輸入時(shí),系統(tǒng)就會(huì)自動(dòng)將這個(gè)中文字符以UTF-8的編碼傳遞給Python。所以如果你的系統(tǒng)是windows操作系統(tǒng),而大多數(shù)情況下windows的系統(tǒng)編碼默認(rèn)是gb2312,那么在windows下做上圖的測(cè)試“小明”這個(gè)字符就是gb2312編碼。

上圖中我們將utf-8編碼的name通過(guò)decode()方法轉(zhuǎn)換為unicode_name,然后通過(guò)encode()方法將unicode_name轉(zhuǎn)換為gb2312_name。這時(shí)我們?cè)儆胮rint去輸出gb2312編碼的字符時(shí)缺產(chǎn)生了一個(gè)奇怪的輸出。這是因?yàn)槲业牟僮飨到y(tǒng)使用的是UTF-8編碼,對(duì)于gb2312編碼的字符自然不能夠正確解析,如果我們將該gb2312的字節(jié)串放在windows下輸出就能夠得到我們想要的中文,如圖:

這里寫(xiě)圖片描述

所謂亂碼本質(zhì)上是系統(tǒng)編碼與所提供字符的編碼不一致導(dǎo)致的,我們舉一個(gè)例子:

小明的電腦中存了一個(gè)utf-8的字母A,存儲(chǔ)在計(jì)算機(jī)中是1100001;

小紅的電腦中也存了一個(gè)gb2312的字母A,存儲(chǔ)在計(jì)算機(jī)中是11000010;

當(dāng)小明與小紅交換信息時(shí),各自的計(jì)算機(jī)就不會(huì)把對(duì)方傳遞過(guò)來(lái)的A識(shí)別為字母A,可能認(rèn)為這是字母B。

所以當(dāng)我們需要操作系統(tǒng)正確的輸出一個(gè)字符時(shí),除了要知道該字符的字符編碼,也要知道自己系統(tǒng)所使用的字符編碼。如果系統(tǒng)使用的是UTF-8編碼,處理的卻是gb2312的字符就會(huì)出現(xiàn)所謂“亂碼”。

一個(gè)Tips:

decode()方法與在字符串前加u的方法實(shí)現(xiàn)的效果相同比如u’小明’

這里寫(xiě)圖片描述

總結(jié):

1.Python2的對(duì)于字符編碼的轉(zhuǎn)換要以u(píng)nicode作為“中間人”進(jìn)行轉(zhuǎn)化。

2.知道自己系統(tǒng)的字符編碼(Linux默認(rèn)utf-8,Windows默認(rèn)GB2312),對(duì)癥下藥。

四、一個(gè)字符編碼的例子

在Linux操作系統(tǒng)下使用python2下獲取網(wǎng)易首頁(yè)的title,并以正確的中文顯示出來(lái)。

這里寫(xiě)圖片描述

163的首頁(yè)使用的字符編碼是gb2312,而我們前面提到過(guò)Linux下的默認(rèn)字符編碼為UTF-8,我們測(cè)試一下直接提取會(huì)不會(huì)出現(xiàn)亂碼問(wèn)題。

這里寫(xiě)圖片描述

我們發(fā)現(xiàn)確實(shí)提取到的title并不能正確顯示,因?yàn)榫W(wǎng)頁(yè)中已經(jīng)聲明了它是一個(gè)gb2312的字符編碼,而我的系統(tǒng)中默認(rèn)的字符編碼為UTF-8顯然,我必須要將title轉(zhuǎn)換為UTF-8的字符。

這里寫(xiě)圖片描述

其實(shí)由于utf-8屬于unicode字符編碼,在Linux中我們可以直接打印出unicode編碼的字符。如:

這里寫(xiě)圖片描述

現(xiàn)在我們?cè)赪indows用Python2來(lái)做另一個(gè)實(shí)驗(yàn),這次我們換成百度首頁(yè)的title:

這里寫(xiě)圖片描述

這次我們發(fā)現(xiàn)網(wǎng)頁(yè)上的字符編碼為utf-8,那么我在Windows下會(huì)不會(huì)出現(xiàn)亂碼:

這里寫(xiě)圖片描述

所以我們?cè)俅螐?qiáng)調(diào):亂碼本質(zhì)上是系統(tǒng)編碼與所提供字符的編碼不一致導(dǎo)致的

在Pyhon3中字符編碼有了很大改善最主要的有以下幾點(diǎn):

1.Python 3的源碼.py文件 的默認(rèn)編碼方式為UTF-8,所以在Python3中你可以不用在py腳本中寫(xiě)coding聲明,并且系統(tǒng)傳遞給python的字符不再受系統(tǒng)默認(rèn)編碼的影響,統(tǒng)一為unicode編碼。

2.將字符串和字節(jié)序列做了區(qū)別,字符串str是字符串標(biāo)準(zhǔn)形式與2.x中unicode類(lèi)似,bytes類(lèi)似2.x中的str有各種編碼區(qū)別。bytes通過(guò)解碼轉(zhuǎn)化成str,str通過(guò)編碼轉(zhuǎn)化成bytes。

PS:有一個(gè)小問(wèn)題被許多新手所困擾,我們來(lái)看一下圖片:

這里寫(xiě)圖片描述

我們看到當(dāng)一個(gè)中文字符出現(xiàn)在一個(gè)list(或tuple、dict)中時(shí),它并不會(huì)被顯示為一個(gè)中文而是字節(jié)串。但當(dāng)該字符串從list中提取出來(lái)再print時(shí)就能夠正常顯示為中文。字節(jié)串是所有字符在python中的“本質(zhì)”形態(tài),所以你可以簡(jiǎn)單的理解為list中呈現(xiàn)出的字節(jié)串是給計(jì)算機(jī)看的。前言:中文編碼問(wèn)題一直是程序員頭疼的問(wèn)題,而Python2中的字符編碼足矣令新手抓狂。本文將盡量用通俗的語(yǔ)言帶大家徹底的了解字符編碼以及Python2和3中的各種編碼問(wèn)題。

一、什么是字符編碼。

要徹底解決字符編碼的問(wèn)題就不能不去了解到底什么是字符編碼。計(jì)算機(jī)從本質(zhì)上來(lái)說(shuō)只認(rèn)識(shí)二進(jìn)制中的0和1,可以說(shuō)任何數(shù)據(jù)在計(jì)算機(jī)中實(shí)際的物理表現(xiàn)形式也就是0和1,如果你將硬盤(pán)拆開(kāi),你是看不到所謂的數(shù)字0和1的,你能看到的只是一塊光滑閃亮的磁盤(pán),如果你用足夠大的放大鏡你就能看到磁盤(pán)的表面有著無(wú)數(shù)的凹凸不平的元件,凹下去的代表0,突出的代表1,這就是計(jì)算機(jī)用來(lái)表現(xiàn)二進(jìn)制的方式。

1.ASCII

現(xiàn)在我們面臨了第一個(gè)問(wèn)題:如何讓人類(lèi)語(yǔ)言,比如英文被計(jì)算機(jī)理解?我們以英文為例,英文中有英文字母(大小寫(xiě))、標(biāo)點(diǎn)符號(hào)、特殊符號(hào)。如果我們將這些字母與符號(hào)給予固定的編號(hào),然后將這些編號(hào)轉(zhuǎn)變?yōu)槎M(jìn)制,那么計(jì)算機(jī)明顯就能夠正確讀取這些符號(hào),同時(shí)通過(guò)這些編號(hào),計(jì)算機(jī)也能夠?qū)⒍M(jìn)制轉(zhuǎn)化為編號(hào)對(duì)應(yīng)的字符再顯示給人類(lèi)去閱讀。由此產(chǎn)生了我們最熟知的ASCII碼。ASCII 碼使用指定的7 位或8 位二進(jìn)制數(shù)組合來(lái)表示128 或256 種可能的字符。這樣在大部分情況下,英文與二進(jìn)制的轉(zhuǎn)換就變得容易多了。

2.GB2312

然而,雖然計(jì)算機(jī)是美國(guó)人發(fā)明的,但是全世界的人都在使用計(jì)算機(jī)。現(xiàn)在出現(xiàn)了另一個(gè)問(wèn)題:如何讓中文被計(jì)算機(jī)理解?這下麻煩了,中文不像拉丁語(yǔ)系是由固定的字母排列組成的。ASCII 碼顯然沒(méi)辦法解決這個(gè)問(wèn)題,為了解決這個(gè)問(wèn)題中國(guó)國(guó)家標(biāo)準(zhǔn)總局1980年發(fā)布《信息交換用漢字編碼字符集》提出了GB2312編碼,用于解決漢字處理的問(wèn)題。1995年又頒布了《漢字編碼擴(kuò)展規(guī)范》(GBK)。GBK與GB 2312—1980國(guó)家標(biāo)準(zhǔn)所對(duì)應(yīng)的內(nèi)碼標(biāo)準(zhǔn)兼容,同時(shí)在字匯一級(jí)支持ISO/IEC10646—1和GB 13000—1的全部中、日、韓(CJK)漢字,共計(jì)20902字。這樣我們就解決了計(jì)算機(jī)處理漢字的問(wèn)題了。

3.Unicode

現(xiàn)在英文和中文問(wèn)題被解決了,但新的問(wèn)題又出現(xiàn)了。全球有那么多的國(guó)家不僅有英文、中文還有阿拉伯語(yǔ)、西班牙語(yǔ)、日語(yǔ)、韓語(yǔ)等等。難不成每種語(yǔ)言都做一種編碼?基于這種情況一種新的編碼誕生了:Unicode。Unicode又被稱(chēng)為統(tǒng)一碼、萬(wàn)國(guó)碼;它為每種語(yǔ)言中的每個(gè)字符設(shè)定了統(tǒng)一并且唯一的二進(jìn)制編碼,以滿(mǎn)足跨語(yǔ)言、跨平臺(tái)進(jìn)行文本轉(zhuǎn)換、處理的要求。Unicode支持歐洲、非洲、中東、亞洲(包括統(tǒng)一標(biāo)準(zhǔn)的東亞象形漢字和韓國(guó)表音文字)。這樣不管你使用的是英文或者中文,日語(yǔ)或者韓語(yǔ),在Unicode編碼中都有收錄,且對(duì)應(yīng)唯一的二進(jìn)制編碼。這樣大家都開(kāi)心了,只要大家都用Unicode編碼,那就不存在這些轉(zhuǎn)碼的問(wèn)題了,什么樣的字符都能夠解析了。

4.UTF-8

但是,由于Unicode收錄了更多的字符,可想而知它的解析效率相比ASCII碼和GB2312的速度要大大降低,而且由于Unicode通過(guò)增加一個(gè)高字節(jié)對(duì)ISO Latin-1字符集進(jìn)行擴(kuò)展,當(dāng)這些高字節(jié)位為0時(shí),低字節(jié)就是ISO Latin-1字符。對(duì)可以用ASCII表示的字符使用Unicode并不高效,因?yàn)閁nicode比ASCII占用大一倍的空間,而對(duì)ASCII來(lái)說(shuō)高字節(jié)的0對(duì)他毫無(wú)用處。為了解決這個(gè)問(wèn)題,就出現(xiàn)了一些中間格式的字符集,他們被稱(chēng)為通用轉(zhuǎn)換格式,即UTF(Unicode Transformation Format)。而我們最常用的UTF-8就是這些轉(zhuǎn)換格式中的一種。在這里我們不去研究UTF-8到底是如何提高效率的,你只需要知道他們之間的關(guān)系即可。

總結(jié):

**1.為了處理英文字符,產(chǎn)生了ASCII碼。
2.為了處理中文字符,產(chǎn)生了GB2312。
3.為了處理各國(guó)字符,產(chǎn)生了Unicode。
4.為了提高Unicode存儲(chǔ)和傳輸性能,產(chǎn)生了UTF-8,它是Unicode的一種實(shí)現(xiàn)形式。**

二、Python2中的字符編碼

1.Python2中默認(rèn)的字符編碼是ASCII碼,也就是說(shuō)Python在處理數(shù)據(jù)時(shí),只要數(shù)據(jù)沒(méi)有指定它的編碼類(lèi)型,Python默認(rèn)將其當(dāng)做ASCII碼來(lái)進(jìn)行處理。這個(gè)問(wèn)題最直接的表現(xiàn)在當(dāng)我們編寫(xiě)的python文件中包含有中文字符時(shí),在運(yùn)行時(shí)會(huì)提示出錯(cuò)。如圖:

這里寫(xiě)圖片描述

這里寫(xiě)圖片描述

這個(gè)問(wèn)題出現(xiàn)的原因是:Python2會(huì)將整個(gè)python腳本中的內(nèi)容當(dāng)做ASCII碼去處理,當(dāng)腳本中出現(xiàn)了中文字符,比如這里的“小明”,我們知道ASCII碼是不能夠處理中文字符的,所以出現(xiàn)了這個(gè)錯(cuò)誤。解決的辦法是:在文件頭部加入一行編碼聲明,如圖:

這里寫(xiě)圖片描述

這里寫(xiě)圖片描述

這樣,Python在處理這個(gè)腳本時(shí),會(huì)用UTF-8的編碼去處理整個(gè)腳本,就能夠正確的解析中文字符了。

2.Python2中字符串有str和unicode兩種類(lèi)型。

這里寫(xiě)圖片描述

上圖中展現(xiàn)出了Python2中字符串的兩種類(lèi)型:

name變量被賦予了一個(gè)字符串“小明”;

unicode_name是name變量的unicode格式,這里我們使用了decode()方法,我們會(huì)在后面的內(nèi)容中詳細(xì)講解;

兩者在終端中返回了不同的字節(jié)串,type返回了不同的數(shù)據(jù)類(lèi)型,但print打印出了相同的輸出。

這里我們注意到一個(gè)“字節(jié)串”的名稱(chēng),字節(jié)串是指該字符串在python中的標(biāo)準(zhǔn)形式,也就是說(shuō)無(wú)論一個(gè)字符串是什么樣的編碼,在python中都會(huì)有一串字節(jié)串來(lái)進(jìn)行表示。字節(jié)串是沒(méi)有編碼的,對(duì)應(yīng)的最終交給計(jì)算機(jī)處理的數(shù)據(jù)形式。

3.Python2中可以直接查看到unicode的字節(jié)串。

在上圖中,輸入unicode_name的返回值,是一個(gè)unicode字節(jié)串,我們能夠直接看到這個(gè)字節(jié)串。而在python3中,我們將不能直接看到unicode字節(jié)串,它會(huì)被顯示為中文的“小明”;因?yàn)閜ython3默認(rèn)使用unicode編碼,unicode字節(jié)串將被直接處理為中文顯示出來(lái)。

總結(jié):

**1.Python2中默認(rèn)的字符編碼是ASCII碼。
2.Python2中字符串有str和unicode兩種類(lèi)型。str有各種編碼的區(qū)別,unicode是沒(méi)有編碼的標(biāo)準(zhǔn)形式。
3.Python2中可以直接查看到unicode的字節(jié)串。**

三、decode()與encode()方法

前面我們說(shuō)了這么多都是為了這一節(jié)做鋪墊,現(xiàn)在我們開(kāi)始來(lái)處理Python2中的字符編碼問(wèn)題。我們首先要學(xué)習(xí)Python為我們提供的兩個(gè)轉(zhuǎn)換編碼的方法decode()與encode()。

***decode()方法將其他編碼字符轉(zhuǎn)化為Unicode編碼字符。
encode()方法將Unicode編碼字符轉(zhuǎn)化為其他編碼字符。*

話(huà)不多說(shuō),直接上圖:

這里寫(xiě)圖片描述

chardet模塊可以檢測(cè)字符串編碼,沒(méi)有該模塊的可以用pip install chardet安裝。

首先解釋一下為什么name=”小明” 這里的小明是一個(gè)utf-8編碼的字符。因?yàn)槲沂褂玫氖荱buntu14.04操作系統(tǒng),系統(tǒng)默認(rèn)的字符編碼就是UTF-8,所以當(dāng)我在終端將一個(gè)中文輸入時(shí),系統(tǒng)就會(huì)自動(dòng)將這個(gè)中文字符以UTF-8的編碼傳遞給Python。所以如果你的系統(tǒng)是windows操作系統(tǒng),而大多數(shù)情況下windows的系統(tǒng)編碼默認(rèn)是gb2312,那么在windows下做上圖的測(cè)試“小明”這個(gè)字符就是gb2312編碼。

上圖中我們將utf-8編碼的name通過(guò)decode()方法轉(zhuǎn)換為unicode_name,然后通過(guò)encode()方法將unicode_name轉(zhuǎn)換為gb2312_name。這時(shí)我們?cè)儆胮rint去輸出gb2312編碼的字符時(shí)缺產(chǎn)生了一個(gè)奇怪的輸出。這是因?yàn)槲业牟僮飨到y(tǒng)使用的是UTF-8編碼,對(duì)于gb2312編碼的字符自然不能夠正確解析,如果我們將該gb2312的字節(jié)串放在windows下輸出就能夠得到我們想要的中文,如圖:

這里寫(xiě)圖片描述

所謂亂碼本質(zhì)上是系統(tǒng)編碼與所提供字符的編碼不一致導(dǎo)致的,我們舉一個(gè)例子:

小明的電腦中存了一個(gè)utf-8的字母A,存儲(chǔ)在計(jì)算機(jī)中是1100001;

小紅的電腦中也存了一個(gè)gb2312的字母A,存儲(chǔ)在計(jì)算機(jī)中是11000010;

當(dāng)小明與小紅交換信息時(shí),各自的計(jì)算機(jī)就不會(huì)把對(duì)方傳遞過(guò)來(lái)的A識(shí)別為字母A,可能認(rèn)為這是字母B。

所以當(dāng)我們需要操作系統(tǒng)正確的輸出一個(gè)字符時(shí),除了要知道該字符的字符編碼,也要知道自己系統(tǒng)所使用的字符編碼。如果系統(tǒng)使用的是UTF-8編碼,處理的卻是gb2312的字符就會(huì)出現(xiàn)所謂“亂碼”。

一個(gè)Tips:

decode()方法與在字符串前加u的方法實(shí)現(xiàn)的效果相同比如u’小明’

這里寫(xiě)圖片描述

總結(jié):

1.Python2的對(duì)于字符編碼的轉(zhuǎn)換要以u(píng)nicode作為“中間人”進(jìn)行轉(zhuǎn)化。

2.知道自己系統(tǒng)的字符編碼(Linux默認(rèn)utf-8,Windows默認(rèn)GB2312),對(duì)癥下藥。

四、一個(gè)字符編碼的例子

在Linux操作系統(tǒng)下使用python2下獲取網(wǎng)易首頁(yè)的title,并以正確的中文顯示出來(lái)。

這里寫(xiě)圖片描述

163的首頁(yè)使用的字符編碼是gb2312,而我們前面提到過(guò)Linux下的默認(rèn)字符編碼為UTF-8,我們測(cè)試一下直接提取會(huì)不會(huì)出現(xiàn)亂碼問(wèn)題。

這里寫(xiě)圖片描述

我們發(fā)現(xiàn)確實(shí)提取到的title并不能正確顯示,因?yàn)榫W(wǎng)頁(yè)中已經(jīng)聲明了它是一個(gè)gb2312的字符編碼,而我的系統(tǒng)中默認(rèn)的字符編碼為UTF-8顯然,我必須要將title轉(zhuǎn)換為UTF-8的字符。

這里寫(xiě)圖片描述

其實(shí)由于utf-8屬于unicode字符編碼,在Linux中我們可以直接打印出unicode編碼的字符。如:

這里寫(xiě)圖片描述

現(xiàn)在我們?cè)赪indows用Python2來(lái)做另一個(gè)實(shí)驗(yàn),這次我們換成百度首頁(yè)的title:

這里寫(xiě)圖片描述

這次我們發(fā)現(xiàn)網(wǎng)頁(yè)上的字符編碼為utf-8,那么我在Windows下會(huì)不會(huì)出現(xiàn)亂碼:

這里寫(xiě)圖片描述

所以我們?cè)俅螐?qiáng)調(diào):亂碼本質(zhì)上是系統(tǒng)編碼與所提供字符的編碼不一致導(dǎo)致的

在Pyhon3中字符編碼有了很大改善最主要的有以下幾點(diǎn):

1.Python 3的源碼.py文件 的默認(rèn)編碼方式為UTF-8,所以在Python3中你可以不用在py腳本中寫(xiě)coding聲明,并且系統(tǒng)傳遞給python的字符不再受系統(tǒng)默認(rèn)編碼的影響,統(tǒng)一為unicode編碼。

2.將字符串和字節(jié)序列做了區(qū)別,字符串str是字符串標(biāo)準(zhǔn)形式與2.x中unicode類(lèi)似,bytes類(lèi)似2.x中的str有各種編碼區(qū)別。bytes通過(guò)解碼轉(zhuǎn)化成str,str通過(guò)編碼轉(zhuǎn)化成bytes。

PS:有一個(gè)小問(wèn)題被許多新手所困擾,我們來(lái)看一下圖片:

這里寫(xiě)圖片描述

我們看到當(dāng)一個(gè)中文字符出現(xiàn)在一個(gè)list(或tuple、dict)中時(shí),它并不會(huì)被顯示為一個(gè)中文而是字節(jié)串。但當(dāng)該字符串從list中提取出來(lái)再print時(shí)就能夠正常顯示為中文。字節(jié)串是所有字符在python中的“本質(zhì)”形態(tài),所以你可以簡(jiǎn)單的理解為list中呈現(xiàn)出的字節(jié)串是給計(jì)算機(jī)看的。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多