欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python編碼問(wèn)題匯總

 更新時(shí)間:2022年03月23日 10:54:05   作者:chenwei  
這篇文章主要給大家分享的是python編碼問(wèn)題匯總,字符編碼簡(jiǎn)單介紹和發(fā)展史及使用方法的一些介紹,文章內(nèi)容詳細(xì),具有一定的參考價(jià)值,需要的小伙伴可以參考一下

一、了解字符編碼的知識(shí)儲(chǔ)備

1. 文本編輯器存取文件的原理(nodepad++,pycharm,word)

 打開(kāi)編輯器就打開(kāi)了啟動(dòng)了一個(gè)進(jìn)程,是在內(nèi)存中的,所以在編輯器編寫(xiě)的內(nèi)容也都是存放與內(nèi)存中的,斷電后數(shù)據(jù)丟失,因而需要保存到硬盤(pán)上,點(diǎn)擊保存按鈕,就從內(nèi)存中把數(shù)據(jù)刷到了硬盤(pán)上。在這一點(diǎn)上,我們編寫(xiě)一個(gè)py文件(沒(méi)有執(zhí)行),跟編寫(xiě)其他文件沒(méi)有任何區(qū)別,都只是在編寫(xiě)一堆字符而已。

即:在沒(méi)有點(diǎn)擊保存時(shí),我們所寫(xiě)的內(nèi)容都是寫(xiě)入內(nèi)存。注意這一點(diǎn),很重要?。‘?dāng)我們點(diǎn)擊保存,內(nèi)容才被刷到硬盤(pán)。

上面做了兩件事:寫(xiě)內(nèi)容到內(nèi)存,從內(nèi)存將內(nèi)存刷到硬盤(pán)。這是兩個(gè)過(guò)程。

2. python解釋器執(zhí)行py文件的原理 

例如:python test.py

  • 第一階段:python解釋器啟動(dòng),此時(shí)就相當(dāng)于啟動(dòng)了一個(gè)文本編輯器
  • 第二階段:python解釋器相當(dāng)于文本編輯器,去打開(kāi)test.py文件,從硬盤(pán)上將test.py的文件內(nèi)容讀入到內(nèi)存中
  • 第三階段:python解釋器解釋執(zhí)行剛剛加載到內(nèi)存中test.py的代碼

python解釋器執(zhí)行py文件分為兩個(gè)步驟:1.將文件讀到內(nèi)存,2.解釋執(zhí)行內(nèi)容。

二、字符編碼簡(jiǎn)介

要搞清楚字符編碼,首先要解決的問(wèn)題是:什么是字符編碼?

我們都知道,計(jì)算機(jī)要想工作必須通電,也就是說(shuō)‘電’驅(qū)使計(jì)算機(jī)干活,而‘電’的特性,就是高低電平(高低平即二進(jìn)制數(shù)1,低電平即二進(jìn)制數(shù)0),也就是說(shuō)計(jì)算機(jī)只認(rèn)識(shí)數(shù)字(010101).如果我們想保存數(shù)據(jù),首先得將我們的數(shù)據(jù)進(jìn)行一些處理,最終得轉(zhuǎn)換成010101才能讓計(jì)算機(jī)識(shí)別。

所以必須經(jīng)過(guò)一個(gè)過(guò)程:

字符--------(翻譯過(guò)程)------->數(shù)字 

這個(gè)過(guò)程實(shí)際就是一個(gè)字符如何對(duì)應(yīng)一個(gè)特定數(shù)字的標(biāo)準(zhǔn),這個(gè)標(biāo)準(zhǔn)稱(chēng)之為字符編碼。

那么問(wèn)題就來(lái)了?作為一種編碼方案,還得解決兩個(gè)問(wèn)題:

  • a.字節(jié)是怎么分組的,如8 bits或16 bits一組,這也被稱(chēng)作編碼單元。
  • b.編碼單元和字符之間的映射關(guān)系。例如,在A(yíng)SCII碼中,十進(jìn)制65映射到字母A上。

ASCII碼是上個(gè)世紀(jì)最流行的編碼體系之一,至少在西方是這樣。下圖顯示了ASCII碼中編碼單元是怎么映射到字符上的。

三、字符編碼的發(fā)展史

階段一:現(xiàn)代計(jì)算機(jī)起源于美國(guó),最早誕生也是基于英文考慮的ASCII

隨著計(jì)算機(jī)越來(lái)越流行,廠(chǎng)商之間的競(jìng)爭(zhēng)更加激烈,在不同的計(jì)算機(jī)體系間轉(zhuǎn)換數(shù)據(jù)變得十分蛋疼,人們厭煩了這種自定義造成的混亂。最終,計(jì)算機(jī)制造商一起制定了一個(gè)標(biāo)準(zhǔn)的方法來(lái)描述字符。他們定義使用一個(gè)字節(jié)的低7位來(lái)表示字符,并且制作了如上圖所示的對(duì)照表來(lái)映射七個(gè)比特的值到一個(gè)字符上。例如,字母A是65,c是99,~是126等等, ASCII碼就這樣誕生了。原始的ASCII標(biāo)準(zhǔn)定義了從0到127 的字符,這樣正好能用七個(gè)比特表示。

為什么選擇了7個(gè)比特而不是8個(gè)來(lái)表示一個(gè)字符呢?我并不關(guān)心。但是一個(gè)字節(jié)是8個(gè)比特,這意味著1個(gè)比特并沒(méi)有被使用,也就是從128到255的編碼并沒(méi)有被制定ASCII標(biāo)準(zhǔn)的人所規(guī)定,這些美國(guó)人對(duì)世界的其它地方一無(wú)所知甚至完全不關(guān)心。其它國(guó)家的人趁這個(gè)機(jī)會(huì)開(kāi)始使用128到255范圍內(nèi)的編碼來(lái)表達(dá)自己語(yǔ)言中的字符。例如,144在阿拉伯人的ASCII碼中是?,而在俄羅斯的ASCII碼中是?。ASCII碼的問(wèn)題在于盡管所有人都在0-127號(hào)字符的使用上達(dá)成了一致,但對(duì)于128-255號(hào)字符卻有很多很多不同的解釋。你必須告訴計(jì)算機(jī)使用哪種風(fēng)格的ASCII碼才能正確顯示128-255號(hào)的字符。

總結(jié):ASCII,一個(gè)Bytes代表一個(gè)字符(英文字符/鍵盤(pán)上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個(gè)字符,ASCII最初只用了后七位,127個(gè)數(shù)字,已經(jīng)完全能夠代表鍵盤(pán)上所有的字符了(英文字符/鍵盤(pán)的所有其他字符),后來(lái)為了將拉丁文也編碼進(jìn)了ASCII表,將最高位也占用了。

階段二:為了滿(mǎn)足中文,中國(guó)人定制了GBK

GBK:2Bytes代表一個(gè)字符;為了滿(mǎn)足其他國(guó)家,各個(gè)國(guó)家紛紛定制了自己的編碼。日本把日文編到Shift_JIS里,韓國(guó)把韓文編到Euc-kr里

階段三:萬(wàn)國(guó)碼Unicode編碼

后來(lái),有人開(kāi)始覺(jué)得太多編碼導(dǎo)致世界變得過(guò)于復(fù)雜了,讓人腦袋疼,于是大家坐在一起拍腦袋想出來(lái)一個(gè)方法:所有語(yǔ)言的字符都用同一種字符集來(lái)表示,這就是Unicode。

Unicode統(tǒng)一用2Bytes代表一個(gè)字符,2**16-1=65535,可代表6萬(wàn)多個(gè)字符,因而兼容萬(wàn)國(guó)語(yǔ)言.但對(duì)于通篇都是英文的文本來(lái)說(shuō),這種編碼方式無(wú)疑是多了一倍的存儲(chǔ)空間(英文字母只需要一個(gè)字節(jié)就足夠,用兩個(gè)字節(jié)來(lái)表示,無(wú)疑是浪費(fèi)空間).于是產(chǎn)生了UTF-8,對(duì)英文字符只用1Bytes表示,對(duì)中文字符用3Bytes.UTF-8是一個(gè)非常驚艷的概念,它漂亮的實(shí)現(xiàn)了對(duì)ASCII碼的向后兼容,以保證Unicode可以被大眾接受。

在UTF-8中,0-127號(hào)的字符用1個(gè)字節(jié)來(lái)表示,使用和US-ASCII相同的編碼。這意味著1980年代寫(xiě)的文檔用UTF-8打開(kāi)一點(diǎn)問(wèn)題都沒(méi)有。只有128號(hào)及以上的字符才用2個(gè),3個(gè)或者4個(gè)字節(jié)來(lái)表示。因此,UTF-8被稱(chēng)作可變長(zhǎng)度編碼。

于是字節(jié)流:0100100001000101010011000100110001001111

這個(gè)字節(jié)流在A(yíng)SCII和UTF-8中表示相同的字符:HELLO

至于其他的UTF-16,這里就不再敘述了。

總結(jié)一點(diǎn):unicode:簡(jiǎn)單粗暴,所有字符都是2Bytes,優(yōu)點(diǎn)是字符----->數(shù)字的轉(zhuǎn)換速度快,缺點(diǎn)是占用空間大。

utf-8:精準(zhǔn),對(duì)不同的字符用不同的長(zhǎng)度表示,優(yōu)點(diǎn)是節(jié)省空間,缺點(diǎn)是:字符->數(shù)字的轉(zhuǎn)換速度慢,因?yàn)槊看味夹枰?jì)算出字符需要多長(zhǎng)的Bytes才能夠準(zhǔn)確表示。

因此,內(nèi)存中使用的編碼是unicode,用空間換時(shí)間(程序都需要加載到內(nèi)存才能運(yùn)行,因而內(nèi)存應(yīng)該是盡可能的保證快);硬盤(pán)中或者網(wǎng)絡(luò)傳輸用utf-8,網(wǎng)絡(luò)I/O延遲或磁盤(pán)I/O延遲要遠(yuǎn)大與utf-8的轉(zhuǎn)換延遲,而且I/O應(yīng)該是盡可能地節(jié)省帶寬,保證數(shù)據(jù)傳輸?shù)姆€(wěn)定性。

所有程序,最終都要加載到內(nèi)存,程序保存到硬盤(pán)不同的國(guó)家用不同的編碼格式,但是到內(nèi)存中我們?yōu)榱思嫒萑f(wàn)國(guó)(計(jì)算機(jī)可以運(yùn)行任何國(guó)家的程序原因在于此),統(tǒng)一且固定使用unicode,這就是為何內(nèi)存固定用unicode的原因,你可能會(huì)說(shuō)兼容萬(wàn)國(guó)我可以用utf-8啊,可以,完全可以正常工作,之所以不用肯定是unicode比utf-8更高效?。╱icode固定用2個(gè)字節(jié)編碼,utf-8則需要計(jì)算),但是unicode更浪費(fèi)空間,沒(méi)錯(cuò),這就是用空間換時(shí)間的一種做法,而存放到硬盤(pán),或者網(wǎng)絡(luò)傳輸,都需要把unicode轉(zhuǎn)成utf-8,因?yàn)閿?shù)據(jù)的傳輸,追求的是穩(wěn)定,高效,數(shù)據(jù)量越小數(shù)據(jù)傳輸就越靠譜,于是都轉(zhuǎn)成utf-8格式的,而不是unicode。

四、字符編碼的使用

不管是哪種類(lèi)型的文件,只要記住一點(diǎn):文件以什么編碼保存的,就以什么編碼方式打開(kāi).

下面我們來(lái)看看python中關(guān)于編碼出現(xiàn)的問(wèn)題:

如果不在python文件指定頭信息#-*-coding:utf-8-*-,那就使用默認(rèn)的python2中默認(rèn)使用ascii,python3中默認(rèn)使用utf-8

讀取已經(jīng)加載到內(nèi)存的代碼(unicode編碼的二進(jìn)制),然后執(zhí)行,執(zhí)行過(guò)程中可能會(huì)開(kāi)辟新的內(nèi)存空間,比如x="hello"

內(nèi)存的編碼使用unicode,不代表內(nèi)存中全都是unicode編碼的二進(jìn)制,在程序執(zhí)行之前,內(nèi)存中確實(shí)都是unicode編碼的二進(jìn)制,比如從文件中讀取了一行x="hello",其中的x,等號(hào),引號(hào),地位都一樣,都是普通字符而已,都是以u(píng)nicode編碼的二進(jìn)制形式存放與內(nèi)存中的.但是程序在執(zhí)行過(guò)程中,會(huì)申請(qǐng)內(nèi)存(與程序代碼所存在的內(nèi)存是倆個(gè)空間),可以存放任意編碼格式的數(shù)據(jù),比如x="hello",會(huì)被python解釋器識(shí)別為字符串,會(huì)申請(qǐng)內(nèi)存空間來(lái)存放"hello",然后讓x指向該內(nèi)存地址,此時(shí)新申請(qǐng)的該內(nèi)存地址保存也是unicode編碼的hello,如果代碼換成x="hello".encode('utf-8'),那么新申請(qǐng)的內(nèi)存空間里存放的就是utf-8編碼的字符串hello了.

瀏覽網(wǎng)頁(yè)的時(shí)候,服務(wù)器會(huì)把動(dòng)態(tài)生成的Unicode內(nèi)容轉(zhuǎn)換為UTF-8再傳輸?shù)綖g覽器

如果服務(wù)端encode的編碼格式是utf-8, 客戶(hù)端內(nèi)存中收到的也是utf-8編碼的二進(jìn)制

五、Python2與python3編碼區(qū)別

1.在python2中有兩種字符串類(lèi)型str和unicode

str類(lèi)型:

當(dāng)python解釋器執(zhí)行到產(chǎn)生字符串的代碼時(shí)(例如s='林'),會(huì)申請(qǐng)新的內(nèi)存地址,然后將'林'編碼成文件開(kāi)頭指定的編碼格式,這已經(jīng)是encode之后的結(jié)果了,所以s只能decode。再次encode就會(huì)報(bào)錯(cuò)。

#_*_coding:gbk_*_
2 #!/usr/bin/env python
3?
4 x='林'
5 # print x.encode('gbk') #報(bào)錯(cuò)
6 print x.decode('gbk') #結(jié)果:林

在python2中,str就是編碼后的結(jié)果bytes,str=bytes,所以在python2中,unicode字符編碼的結(jié)果是str/bytes。

#coding:utf-8
s='林' #在執(zhí)行時(shí),'林'會(huì)被以conding:utf-8的形式保存到新的內(nèi)存空間中

print repr(s) #'\xe6\x9e\x97' 三個(gè)Bytes,證明確實(shí)是utf-8
print type(s) #<type 'str'>

s.decode('utf-8')
# s.encode('utf-8') #報(bào)錯(cuò),s為編碼后的結(jié)果bytes,所以只能decode

Unicode類(lèi)型:

當(dāng)python解釋器執(zhí)行到產(chǎn)生字符串的代碼時(shí)(例如s=u'林'),會(huì)申請(qǐng)新的內(nèi)存地址,然后將'林'以u(píng)nicode的格式存放到新的內(nèi)存空間中,所以s只能encode,不能decode.

s=u'林'
print repr(s) #u'\u6797'
print type(s) #<type 'unicode'>


# s.decode('utf-8') #報(bào)錯(cuò),s為unicode,所以只能encode
s.encode('utf-8')?

特別說(shuō)明:

當(dāng)數(shù)據(jù)要打印到終端時(shí),要注意一些問(wèn)題.

當(dāng)程序執(zhí)行時(shí),比如:x='林';print(x) #這一步是將x指向的那塊新的內(nèi)存空間(非代碼所在的內(nèi)存空間)中的內(nèi)存,打印到終端,而終端仍然是運(yùn)行于內(nèi)存中的,所以這打印可以理解為從內(nèi)存打印到內(nèi)存,即內(nèi)存->內(nèi)存,unicode->unicode.對(duì)于unicode格式的數(shù)據(jù)來(lái)說(shuō),無(wú)論怎么打印,都不會(huì)亂碼.python3中的字符串與python2中的u'字符串',都是unicode,所以無(wú)論如何打印都不會(huì)亂碼.在windows終端(終端編碼為gbk,文件編碼為utf-8,亂碼產(chǎn)生)

#分別驗(yàn)證在pycharm中和cmd中下述的打印結(jié)果
s=u'林' #當(dāng)程序執(zhí)行時(shí),'林'會(huì)被以u(píng)nicode形式保存新的內(nèi)存空間中


#s指向的是unicode,因而可以編碼成任意格式,都不會(huì)報(bào)encode錯(cuò)誤
s1=s.encode('utf-8')
s2=s.encode('gbk')
print s1 #打印正常否?
print s2 #打印正常否


print repr(s) #u'\u6797'
print repr(s1) #'\xe6\x9e\x97' 編碼一個(gè)漢字utf-8用3Bytes
print repr(s2) #'\xc1\xd6' 編碼一個(gè)漢字gbk用2Bytes

print type(s) #<type 'unicode'>
print type(s1) #<type 'str'>
print type(s2) #<type 'str'>

2. 在python3中也有兩種字符串類(lèi)型str和bytes

str類(lèi)型變?yōu)閡nicode類(lèi)型:

#coding:utf-8
s='林' #當(dāng)程序執(zhí)行時(shí),無(wú)需加u,'林'也會(huì)被以u(píng)nicode形式保存新的內(nèi)存空間中,

#s可以直接encode成任意編碼格式
s.encode('utf-8')
s.encode('gbk')

print(type(s)) #<class 'str'>

bytes類(lèi)型:

#coding:utf-8
s='林' #當(dāng)程序執(zhí)行時(shí),無(wú)需加u,'林'也會(huì)被以u(píng)nicode形式保存新的內(nèi)存空間中,

#s可以直接encode成任意編碼格式
s1=s.encode('utf-8')
s2=s.encode('gbk')

print(s) #林
print(s1) #b'\xe6\x9e\x97' 在python3中,是什么就打印什么
print(s2) #b'\xc1\xd6' 同上

print(type(s)) #<class 'str'>
print(type(s1)) #<class 'bytes'>
print(type(s2)) #<class 'bytes'>
  

到此這篇關(guān)于python編碼問(wèn)題匯總的文章就介紹到這了,更多相關(guān)python編碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python實(shí)現(xiàn)京東秒殺功能代碼

    Python實(shí)現(xiàn)京東秒殺功能代碼

    這篇文章主要介紹了Python實(shí)現(xiàn)京東秒殺功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Django路由層如何獲取正確的url

    Django路由層如何獲取正確的url

    本文介紹路由層是如何進(jìn)行路由匹配的,以diango1.x版本為例,文中通過(guò)示例代碼介紹的非常詳細(xì),文中通過(guò)示例代碼介紹的非常詳細(xì),
    2021-07-07
  • PyCharm 2020.2.2 x64 下載并安裝的詳細(xì)教程

    PyCharm 2020.2.2 x64 下載并安裝的詳細(xì)教程

    這篇文章主要介紹了PyCharm 2020.2.2 x64 下載并安裝的詳細(xì)教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 對(duì)Python3中列表乘以某一個(gè)數(shù)的示例詳解

    對(duì)Python3中列表乘以某一個(gè)數(shù)的示例詳解

    今天小編就為大家分享一篇對(duì)Python3中列表乘以某一個(gè)數(shù)的示例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • 詳解python文件的操作和異常的處理

    詳解python文件的操作和異常的處理

    這篇文章主要為大家介紹了python文件的操作和異常的處理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)對(duì)切片命名清除索引的方法

    Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)對(duì)切片命名清除索引的方法

    這篇文章主要介紹了Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)對(duì)切片命名清除索引的方法,結(jié)合實(shí)例形式分析了Python字符串截取及indices方法映射序列的相關(guān)操作技巧,需要的朋友可以參考下
    2018-03-03
  • python判斷一個(gè)集合是否為另一個(gè)集合的子集方法

    python判斷一個(gè)集合是否為另一個(gè)集合的子集方法

    下面小編就為大家分享一篇python判斷一個(gè)集合是否為另一個(gè)集合的子集方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 在python中創(chuàng)建表格的兩種方法實(shí)例

    在python中創(chuàng)建表格的兩種方法實(shí)例

    Python 是一種解釋型、面向?qū)ο?、?dòng)態(tài)數(shù)據(jù)類(lèi)型的高級(jí)程序設(shè)計(jì)語(yǔ)言,下面這篇文章主要給大家介紹了關(guān)于如何在python中創(chuàng)建表格的兩種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • flask中使用藍(lán)圖將路由分開(kāi)寫(xiě)在不同文件實(shí)例解析

    flask中使用藍(lán)圖將路由分開(kāi)寫(xiě)在不同文件實(shí)例解析

    這篇文章主要介紹了flask中使用藍(lán)圖將路由分開(kāi)寫(xiě)在不同文件實(shí)例解析,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • scipy稀疏數(shù)組coo_array的實(shí)現(xiàn)

    scipy稀疏數(shù)組coo_array的實(shí)現(xiàn)

    本文主要介紹了scipy稀疏數(shù)組coo_array的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02

最新評(píng)論