python基礎之字符編碼

閱讀目錄

一 了解字符編碼的知識儲備

一 計算機基礎知識

?

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

#1、打開編輯器就打開了啟動了一個進程,是在內存中的,所以,用編輯器編寫的內容也都是存放與內存中的,斷電后數據丟失#2、要想永久保存,需要點擊保存按鈕:編輯器把內存的數據刷到了硬盤上。#3、在我們編寫一個py文件(沒有執行),跟編寫其他文件沒有任何區別,都只是在編寫一堆字符而已。

三 python解釋器執行py文件的原理 ,例如python test.py

復制代碼
#第一階段:python解釋器啟動,此時就相當于啟動了一個文本編輯器#第二階段:python解釋器相當于文本編輯器,去打開test.py文件,從硬盤上將test.py的文件內容讀入到內存中(小復習:pyhon的解釋性,決定了解釋器只關心文件內容,不關心文件后綴名)#第三階段:python解釋器解釋執行剛剛加載到內存中test.py的代碼( ps:在該階段,即真正執行代碼時,才會識別python的語法,執行文件內代碼,當執行到name="egon"時,會開辟內存空間存放字符串"egon")
復制代碼

四?總結python解釋器與文件本編輯的異同

#1、相同點:python解釋器是解釋執行文件內容的,因而python解釋器具備讀py文件的功能,這一點與文本編輯器一樣#2、不同點:文本編輯器將文件內容讀入內存后,是為了顯示或者編輯,根本不去理會python的語法,而python解釋器將文件內容讀入內存后,可不是為了給你瞅一眼python代碼寫的啥,而是為了執行python代碼、會識別python語法。

二 字符編碼介紹

一 什么是字符編碼

復制代碼
  計算機要想工作必須通電,即用‘電’驅使計算機干活,也就是說‘電’的特性決定了計算機的特性。電的特性即高低電平(人類從邏輯上將二進制數1對應高電平,二進制數0對應低電平),關于磁盤的磁特性也是同樣的道理。結論:計算機只認識數字很明顯,我們平時在使用計算機時,用的都是人類能讀懂的字符(用高級語言編程的結果也無非是在文件內寫了一堆字符),如何能讓計算機讀懂人類的字符?必須經過一個過程:#字符--------(翻譯過程)------->數字 #這個過程實際就是一個字符如何對應一個特定數字的標準,這個標準稱之為字符編碼
復制代碼

二?以下兩個場景下涉及到字符編碼的問題:

#1、一個python文件中的內容是由一堆字符組成的,存取均涉及到字符編碼問題(python文件并未執行,前兩個階段均屬于該范疇)#2、python中的數據類型字符串是由一串字符組成的(python文件執行時,即第三個階段)

三 字符編碼的發展史與分類(了解)

計算機由美國人發明,最早的字符編碼為ASCII,只規定了英文字母數字和一些特殊字符與數字的對應關系。最多只能用 8 位來表示(一個字節),即:2**8 = 256,所以,ASCII碼最多只能表示 256 個符號

當然我們編程語言都用英文沒問題,ASCII夠用,但是在處理數據時,不同的國家有不同的語言,日本人會在自己的程序中加入日文,中國人會加入中文。

而要表示中文,單拿一個字節表表示一個漢子,是不可能表達完的(連小學生都認識兩千多個漢字),解決方法只有一個,就是一個字節用>8位2進制代表,位數越多,代表的變化就多,這樣,就可以盡可能多的表達出不通的漢字

所以中國人規定了自己的標準gb2312編碼,規定了包含中文在內的字符->數字的對應關系。

日本人規定了自己的Shift_JIS編碼

韓國人規定了自己的Euc-kr編碼(另外,韓國人說,計算機是他們發明的,要求世界統一用韓國編碼,但世界人民沒有搭理他們)

?

這時候問題出現了,精通18國語言的小周同學謙虛的用8國語言寫了一篇文檔,那么這篇文檔,按照哪國的標準,都會出現亂碼(因為此刻的各種標準都只是規定了自己國家的文字在內的字符跟數字的對應關系,如果單純采用一種國家的編碼格式,那么其余國家語言的文字在解析時就會出現亂碼)

所以迫切需要一個世界的標準(能包含全世界的語言)于是unicode應運而生(韓國人表示不服,然后沒有什么卵用)

ascii用1個字節(8位二進制)代表一個字符

unicode常用2個字節(16位二進制)代表一個字符,生僻字需要用4個字節

例:

字母x,用ascii表示是十進制的120,二進制0111 1000

漢字已經超出了ASCII編碼的范圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101

字母x,用unicode表示二進制0000 0000 0111 1000,所以unicode兼容ascii,也兼容萬國,是世界的標準

?

這時候亂碼問題消失了,所有的文檔我們都使用但是新問題出現了,如果我們的文檔通篇都是英文,你用unicode會比ascii耗費多一倍的空間,在存儲和傳輸上十分的低效

本著節約的精神,又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節,常用的英文字母被編碼成1個字節,漢字通常是3個字節,只有很生僻的字符才會被編碼成4-6個字節。如果你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間:

字符ASCIIUnicodeUTF-8
A0100000100000000 0100000101000001
x01001110 0010110111100100 10111000 10101101

從上面的表格還可以發現,UTF-8編碼有一個額外的好處,就是ASCII編碼實際上可以被看成是UTF-8編碼的一部分,所以,大量只支持ASCII編碼的歷史遺留軟件可以在UTF-8編碼下繼續工作。

四 總結字符編碼的發展可分為三個階段(重要)

?!!!重點!!!

三 字符編碼應用之文件編輯器

3.1 文本編輯器之nodpad++

?

?!!!亂碼分析!!!?

3.2 文本編輯器之pycharm

以utf-8格式打開(選擇reload)

?pycharm中:reload與convert的區別

3.3 文本編輯器之python解釋器

復制代碼
文件test.py以gbk格式保存,內容為:x='林'無論是python2 test.py還是python3 test.py都會報錯(因為python2默認ascii,python3默認utf-8)除非在文件開頭指定#coding:gbk
復制代碼

3.4 總結

!!!總結非常重要的兩點!!!

#1、保證不亂嗎的核心法則就是,字符按照什么標準而編碼的,就要按照什么標準解碼,此處的標準指的就是字符編碼#2、在內存中寫的所有字符,一視同仁,都是unicode編碼,比如我們打開編輯器,輸入一個“你”,我們并不能說“你”就是一個漢字,此時它僅僅只是一個符號,該符號可能很多國家都在使用,根據我們使用的輸入法不同這個字的樣式可能也不太一樣。只有在我們往硬盤保存或者基于網絡傳輸時,才能確定”你“到底是一個漢字,還是一個日本字,這就是unicode轉換成其他編碼格式的過程了

? ? ? ? ? ? ? ? ? unicode----->encode-------->utf-8

? ? ? ? ? ? ? ? ? utf-8-------->decode---------->unicode

#補充:瀏覽網頁的時候,服務器會把動態生成的Unicode內容轉換為UTF-8再傳輸到瀏覽器如果服務端encode的編碼格式是utf-8, 客戶端內存中收到的也是utf-8編碼的結果。

?

四 字符編碼應用之python

4.1 執行python程序的三個階段

python test.py ? (我再強調一遍,執行test.py的第一步,一定是先將文件內容讀入到內存中)

test.py文件內容以gbk格式保存的,內容為:

階段一:啟動python解釋器

階段二:python解釋器此時就是一個文本編輯器,負責打開文件test.py,即從硬盤中讀取test.py的內容到內存中

此時,python解釋器會讀取test.py的第一行內容,#coding:utf-8,來決定以什么編碼格式來讀入內存,這一行就是來設定python解釋器這個軟件的編碼使用的編碼格式這個編碼,可以用sys.getdefaultencoding()查看,如果不在python文件指定頭信息#-*-coding:utf-8-*-,那就使用默認的python2中默認使用ascii,python3中默認使用utf-8?

?

改正:在test.py指定文件頭,字符編碼一定要為gbk,

#coding:gbk
你好啊

階段三:讀取已經加載到內存的代碼(unicode編碼格式),然后執行,執行過程中可能會開辟新的內存空間,比如x="egon"

復制代碼
內存的編碼使用unicode,不代表內存中全都是unicode,在程序執行之前,內存中確實都是unicode,比如從文件中讀取了一行x="egon",其中的x,等號,引號,地位都一樣,都是普通字符而已,都是以unicode的格式存放于內存中的但是程序在執行過程中,會申請內存(與程序代碼所存在的內存是倆個空間)用來存放python的數據類型的值,而python的字符串類型又涉及到了字符的概念比如x="egon",會被python解釋器識別為字符串,會申請內存空間來存放字符串類型的值,至于該字符串類型的值被識別成何種編碼存放,這就與python解釋器的有關了,而python2與python3的字符串類型又有所不同。 
復制代碼

4.2 python2與python3字符串類型的區別

一 在python2中有兩種字符串類型str和unicode

str類型

當python解釋器執行到產生字符串的代碼時(例如x='上'),會申請新的內存地址,然后將'上'編碼成文件開頭指定的編碼格式

要想看x在內存中的真實格式,可以將其放入列表中再打印,而不要直接打印,因為直接print()會自動轉換編碼,這一點我們稍后再說。

#coding:gbk
x='上'
y='下'
print([x,y]) #['\xc9\xcf', '\xcf\xc2']
#\x代表16進制,此處是c9cf總共4位16進制數,一個16進制四4個比特位,4個16進制數則是16個比特位,即2個Bytes,這就證明了按照gbk編碼中文用2Bytes
print(type(x),type(y)) #(<type 'str'>, <type 'str'>)

理解字符編碼的關鍵!!!

內存中的數據通常用16進制表示,2位16進制數據代表一個字節,如\xc9,代表兩位16進制,一個字節

gbk存中文需要2個bytes,而存英文則需要1個bytes,它是如何做到的???!!!

gbk會在每個bytes,即8位bit的第一個位作為標志位,標志位為1則表示是中文字符,如果標志位為0則表示為英文字符

x=‘你a好’
轉成gbk格式二進制位
8bit+8bit+8bit+8bit+8bit=(1+7bit)+(1+7bit)+(0+7bit)+(1+7bit)+(1+7bit)

這樣計算機按照從左往右的順序讀:

#連續讀到前兩個括號內的首位標志位均為1,則構成一個中午字符:你#讀到第三個括號的首位標志為0,則該8bit代表一個英文字符:a#連續讀到后兩個括號內的首位標志位均為1,則構成一個中午字符:好

也就是說,每個Bytes留給我們用來存真正值的有效位數只有7位,而在unicode表中存放的只是這有效的7位,至于首位的標志位與具體的編碼有關,即在unicode中表示gbk的方式為:

(7bit)+(7bit)+(7bit)+(7bit)+(7bit)

?

按照上圖翻譯的結果,我們可以去unicode關于漢字的對應關系中去查:鏈接:https://pan.baidu.com/s/1dEV3RYp

?

可以看到“”上“”對應的gbk(G0代表的是gbk)編碼就為494F,即我們得出的結果,而上對應的unicode編碼為4E0A,我們可以將gbk-->decode-->unicode

#coding:gbk
x='上'.decode('gbk')
y='下'.decode('gbk')
print([x,y]) #[u'\u4e0a', u'\u4e0b']

unicode類型

當python解釋器執行到產生字符串的代碼時(例如s=u'林'),會申請新的內存地址,然后將'林'以unicode的格式存放到新的內存空間中,所以s只能encode,不能decode

#coding:gbk
x=u'上' #等同于 x='上'.decode('gbk')
y=u'下' #等同于 y='下'.decode('gbk')
print([x,y]) #[u'\u4e0a', u'\u4e0b']
print(type(x),type(y)) #(<type 'unicode'>, <type 'unicode'>)

打印到終端

對于print需要特別說明的是:

當程序執行時,比如

x='上' #gbk下,字符串存放為\xc9\xcf

print(x) #這一步是將x指向的那塊新的內存空間(非代碼所在的內存空間)中的內存,打印到終端,按理說應該是存的什么就打印什么,但打印\xc9\xcf,對一些不熟知python編碼的程序員,立馬就懵逼了,所以龜叔自作主張,在print(x)時,使用終端的編碼格式,將內存中的\xc9\xcf轉成字符顯示,此時就需要終端編碼必須為gbk,否則無法正常顯示原內容:上

對于unicode格式的數據來說,無論怎么打印,都不會亂碼

unicode這么好,不會亂碼,那python2為何還那么別扭,搞一個str出來呢?python誕生之時,unicode并未像今天這樣普及,很明顯,好的東西你能看得見,龜叔早就看見了,龜叔在python3中將str直接存成unicode,我們定義一個str,無需加u前綴,就是一個unicode,屌不屌?

?

二 在python3 中也有兩種字符串類型str和bytes

str是unicode

復制代碼
#coding:gbk
x='上' #當程序執行時,無需加u,'上'也會被以unicode形式保存新的內存空間中,print(type(x)) #<class 'str'>#x可以直接encode成任意編碼格式
print(x.encode('gbk')) #b'\xc9\xcf'
print(type(x.encode('gbk'))) #<class 'bytes'>
復制代碼

很重要的一點是:看到python3中x.encode('gbk') 的結果\xc9\xcf正是python2中的str類型的值,而在python3是bytes類型,在python2中則是str類型

于是我有一個大膽的推測:python2中的str類型就是python3的bytes類型,于是我查看python2的str()源碼,發現

轉載于:https://www.cnblogs.com/iamjianghao/p/8028890.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/278146.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/278146.shtml
英文地址,請注明出處:http://en.pswp.cn/news/278146.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# WinForm開發系列 - DataGridView

1.DataGridView實現課程表 testcontrol.rar 2.DataGridView二維表頭及單元格合并 DataGridView單元格合并和二維表頭.rar myMultiColHeaderDgv.rar 3.DataGridView單元格顯示GIF圖片 gifanimationindatagrid.rar 4.自定義顯示DataGridView列(行頭顯示行號與圖標,同一單元格顯示…

ruby語法_Ruby函數(方法)語法

ruby語法The Ruby language makes it easy to create functions. Ruby語言使創建函數變得容易。 Function Syntax 功能語法 def functionname(variable) return <value>end def functionname(variable)return <值>結束Examples 例子 Your function can compute …

011-git-將tag推送到遠端

1、將tag推送到遠端 在使用TortoiseGit過程中&#xff0c;push推送過程中&#xff0c;選擇include tag&#xff0c;遠端就有次分支。

pageadmin CMS網站建設教程:站點添加自定義字段

首先看看pagedmin默認的站點設置都有什么&#xff0c;如下圖&#xff1a; 這里只有一些最基本的參數設置&#xff0c;用過3.0版本或用過其他公司開發的cms的用戶應該有這種體驗&#xff0c;在站點設置中可以設置logo圖片&#xff0c;備案號&#xff0c;底部內容等等。 那么為什…

如何將世界時鐘和時區小部件添加到您的iPhone

When you work remotely or have friends and family who live in another country, it’s important to know what time it is across time zones. A world clock (or time zone) widget on your iPhone’s Home screen makes this much easier. 當您遠程工作或有家人和朋友居…

Python網絡爬蟲之三種數據解析方式

引入 回顧requests實現數據爬取的流程 指定url基于requests模塊發起請求獲取響應對象中的數據進行持久化存儲其實&#xff0c;在上述流程中還需要較為重要的一步&#xff0c;就是在持久化存儲之前需要進行指定數據解析。因為大多數情況下的需求&#xff0c;我們都會指定去使用聚…

一行代碼實現底部導航欄TabLayout

歡迎關注公眾號&#xff1a;JueCode app中底部導航欄已經是很常見的控件了&#xff0c;比如微信&#xff0c;簡書&#xff0c;QQ等都有這類控件&#xff0c;都是點擊底部標簽切換界面。主要的實現手段有 RadioGroupFragmentTabLayoutTabLayoutBottom Navigation其中TabLayout一…

小程序視頻截gif_3個簡單的應用程序,可讓您深入視頻和GIF

小程序視頻截gifDeepfakes make it possible to manipulate videos and GIFs. The technology has become so easy to use, you can now create deepfakes right on your phone. That’s right—you can now easily insert yourself into a meme. 借助Deepfake &#xff0c;可以…

【AtCoder】ARC095 E - Symmetric Grid 模擬

【題目】E - Symmetric Grid 【題意】給定n*m的小寫字母矩陣&#xff0c;求是否能通過若干行互換和列互換使得矩陣中心對稱。n,m<12。 【算法】模擬 【題解】首先行列操作獨立&#xff0c;如果已確定行操作&#xff0c;那么兩個在對稱位置的列要滿足條件必須其中一列反轉后和…

一、內存尋址

1.內存地址分類: 邏輯地址、線性地址、物理地址 邏輯地址:段選擇符偏移量 線性地址:C語言中取地址符&打印出來的地址就是這個地址&#xff0c;也叫虛擬地址。 物理地址:內存總線尋址的具體地址&#xff0c;是真實存在的。 邏輯地址通過分段單元轉換成線性地址&#xff0c;線…

如何使用Google TV設置Chromecast

Justin Duino賈斯汀杜伊諾(Justin Duino)Google changed up its streaming platform with the release of the Chromecast with Google TV. Instead of being a Cast-only device like Chromecasts before it, Google’s latest dongle runs the successor of Android TV. If y…

js之 foreach, map, every, some

js中array有四個方法 foreach, map, every, some&#xff0c;其使用各有傾向。 關注點一&#xff1a;foreach 和 map 無法跳出循環&#xff0c;每個元素均執行foreach 和 map 無法跳出循環&#xff0c;他們是對每個數組元素調用 callback&#xff1b; foreach 無返回值&#xf…

scala 方法、函數定義小結

2019獨角獸企業重金招聘Python工程師標準>>> package scalapackage.testmethod/*** Created by Germmy on 2018/4/15.*/ object TesMethod {def main(args: Array[String]) {//定義方法的一種方法,高階函數的一種定義方法def m1(x:Int)(y:Int)x*yval resm1(3)(4)pri…

ipad和iphone切圖_如何在iPhone和iPad上密碼保護照片

ipad和iphone切圖Sometimes, you need to protect your iPhone or iPad photos from prying eyes that might also have access to your device. Unfortunately, Apple doesn’t provide an obvious, secure way to do this. However, there’s a work-around thanks to the No…

Java高級篇(二)——網絡通信

網絡編程是每個開發人員工具箱中的核心部分&#xff0c;我們在學習了諸多Java的知識后&#xff0c;也將步入幾個大的方向&#xff0c;Java網絡編程就是其中之一。 如今強調網絡的程序不比涉及網絡的更多。除了經典的應用程序&#xff0c;如電子郵件、Web瀏覽器和遠程登陸外&…

Navigator 對象,能夠清楚地知道瀏覽器的相關信息

Navigator 對象屬性 appCodeName屬性 功能&#xff1a;返回瀏覽器的代碼名。該屬性是一個只讀的字符串。 語法&#xff1a;navigator.appCodeName 總結&#xff1a;在所有以Netscape代碼為基礎的瀏覽器中&#xff0c;它的值是"Mozilla"。為了兼容起見&#xff0c;在M…

Jerry和您聊聊Chrome開發者工具

2019獨角獸企業重金招聘Python工程師標準>>> Chrome開發者工具是Jerry日常工作使用的三大調試器之一。雖然工具名稱前面帶了個"開發者", 但是它對非開發人員仍然有用。不信&#xff1f; 用Chrome打開我們常用的網站&#xff0c;按F12&#xff0c;在Consol…

BZOJ4314 倍數?倍數!

好神仙啊.... 題意 在$ [0,n) $中選$ k$個不同的數使和為$ n$的倍數 求方案數 $ n \leq 10^9, \ k \leq 10^3$ 題解 k可以放大到1e6的 先不考慮$ k$的限制 對答案構建多項式$ f(x)\prod\limits_{i0}^{n-1}(x^i1)$ 答案就是這個多項式所有次數為$ n$的倍數的項的系數和 考慮單位…

win2008R2管理員密碼修改文檔

場景&#xff1a;忘記了win2008R2服務器的管理員密碼。解決辦法&#xff1a;1、 制作一個U盤啟動盤&#xff1a;2、 系統通過U盤啟動進入WINpe系統3、 在知道Win2008安裝位置的情況下&#xff1b;查找C:\windows\system32\osk.exe 將osk.exe文件修改為&#xff1a;osk.exe.bat&…

Python檔案袋( 面向對象 )

類即是一個模型&#xff0c;根據模型建立起不同的對象&#xff0c;對象間擁有共同的一些屬性 簡單的類&#xff1a; 1 class P:2 #類變量&#xff0c;所有實例共享變量,推薦使用方法是&#xff1a;類名.類變量名3 pvarx"ppvar1"4 5 #構造函數6 def _…