Python字符編碼與函數(shù)的基本使用方法
一、Python2中的字符存在的解碼編碼問(wèn)題
如果是現(xiàn)在正在用Python2的人應(yīng)該都知道存在字符編碼問(wèn)題,就舉一個(gè)最簡(jiǎn)單的例子吧:Python2是無(wú)法在命令行直接打印中文的,當(dāng)然他也是不會(huì)報(bào)錯(cuò)的,頂多是一堆你看不懂的亂碼。如果想在直接顯示中文,我們是可以在Python2文件頭部申明字符編碼的格式。如下圖
這里 #-*-coding:utf-8 -*- 是用來(lái)申明下面的代碼是用什么編碼來(lái)解釋;
1.1.Python2中的解碼和編碼:
在編碼和解碼的世界中,我們得需要找一個(gè)大家都知道的文字。也可以這么理解。我是一個(gè)中國(guó)人現(xiàn)在和一個(gè)日本人溝通,我肯定是無(wú)法理解他說(shuō)的是什么,他同樣也無(wú)法理解,但是這樣就沒(méi)有辦法了嗎?或許我們需要一個(gè)國(guó)際的語(yǔ)言——英語(yǔ)。這樣來(lái)自不同國(guó)家的人也可以進(jìn)行溝通了(雖然我知道 are you ok 0-0)。在編碼中也是一樣,gbk和utf-8都不知道對(duì)方的格式是什么吊意思。所以如果要上gbk讀懂utf-8的編碼就得將utf-8 decode成 Unicode,而Unicode有知道gkb,這里需要將Unicode在encode成gbk就行了
#-*- coding:utf-8 -*- msg = "中國(guó)" print msg #解碼在編碼的過(guò)程,encoding是申明用申明這段代碼是什么編碼 gbk_str = msg.decode(encoding='utf-8').encode(encoding='gbk') print gbk_str #其實(shí)兩種輸出的結(jié)果是一樣的
在Python2中默認(rèn)是使用gbk來(lái)解釋IDE中的代碼的,所以無(wú)法直接在Python命令行中直接輸入中文,所以我們才會(huì)使用 #-*-coding:utf-8 -*-來(lái)申明頭部,我們到底需要使用什么語(yǔ)言來(lái)解釋下面代碼。細(xì)心的人肯定是發(fā)現(xiàn)了一個(gè)問(wèn)題,申明頭部只是使用utf-8來(lái)解釋下面的話,按理說(shuō)命令行中雖然不報(bào)錯(cuò),但是應(yīng)該也是亂碼才是,這里為啥會(huì)直接輸出中文呢畢竟DOS命令行中默認(rèn)支持的是gbk格式的字符代碼呀?這里就涉及到另外的一個(gè)概念了。Python到內(nèi)存解釋器里面,默認(rèn)是用的Unicode,文件加載到內(nèi)存后自動(dòng)解碼成Unicode,而Unicode是外國(guó)碼,自然也就可以翻譯來(lái)自u(píng)tf-8的編碼,也可以翻譯成gbk的編碼了。顧可以顯示中文了。
PS:這里我們得出一個(gè)結(jié)論:python2 中解碼動(dòng)作是必須的,但是編碼可以不用,因?yàn)閮?nèi)存就是Unicode
1.2、Python3中字符編碼的問(wèn)題:
額,這還有什么可以說(shuō)的呢?Python3默認(rèn)就是使用utf-8解釋代碼的。也就是行首自帶 #-*-coding:utf-8 -*-(GBM),所以也就不存在解碼的問(wèn)題。但是我在這里提上一嘴(其實(shí)就是怕自己以后也忘了,嘿嘿),如果我們將utf-8的字符編碼的格式給編碼成gbk。這里會(huì)輸出bytes格式的東西。
bytes到底是什么東西呢?這里我簡(jiǎn)單的說(shuō)一下。其實(shí)就是這個(gè)字符在ASCII碼中對(duì)應(yīng)的位置。不信,我們通過(guò)一段代碼截圖看看:
在這一幅圖中我們看到中國(guó)被傳成了一堆看不懂的鳥(niǎo)文。而英文還是顯示出來(lái)了。但是我們通過(guò)列表的截取,看出最后一位的c輸出的是99,其實(shí)這里輸出的就是ASCII中c對(duì)應(yīng)的位置,而3個(gè)bytes是一個(gè)中文,所以我們看到了6段鳥(niǎo)文字,這里我們就不過(guò)多解釋了。
PS:大家得記得一個(gè)東西就是:Python2 里面的str 就是Python3中的bytes格式,而Python2中的str其實(shí)就是Unicode
二、Python3對(duì)文件操作補(bǔ)充
2.1、帶“+”的文件操作:
在這里我會(huì)說(shuō)三個(gè),但是其實(shí)這些東西都沒(méi)有什么鳥(niǎo)用,只是這算上一個(gè)知識(shí)點(diǎn)
r+: 可讀,可以追加
w+:清空源文件,再寫(xiě)入新內(nèi)容
a+:追加,可以讀
f = open('lyrics','r+',encoding='utf-8') #這里的lyrics是文件名字 f.read() #我先讀取 f.write("Leon Have Dream") #在后面追加 f.close()
r+:如果是先f(wàn).read()再f.write()就是在文件的結(jié)尾追加,如果是直接f.write()就直接將文件開(kāi)始的內(nèi)容替換成()中的內(nèi)容;
f = open('lyricsback','w+',encoding='utf-8') f.read() f.write("Leon Have Dream") f.read() f.close()
w+:其實(shí)就是清空內(nèi)容再重新寫(xiě)入write()中的內(nèi)容,并且f.read()也不會(huì)報(bào)錯(cuò),個(gè)人建議可以在快要離職的時(shí)候執(zhí)行這個(gè)操作
f = open('lyricsback','a+',encoding='utf-8') f.read() f.write("Leon Have A Draem") f.read() f.close()
a+:其實(shí)和r+非常相似是在結(jié)尾中追加內(nèi)容,可讀內(nèi)容
PS:這里的補(bǔ)充一下,為什么在使用r+的時(shí)候先執(zhí)行f.read()再執(zhí)行f.write()就會(huì)在文件的結(jié)尾追加和直接使用f.write()直接就替換文件最前邊的內(nèi)容呢?這是因?yàn)镻ython在讀文件的時(shí)候自己維護(hù)這一個(gè)“指針”,如果我們使用f.read()就相當(dāng)于讀完了這個(gè)文件,這時(shí)候指針也就會(huì)在最后面了。下面我在補(bǔ)充“f”這個(gè)對(duì)象的幾個(gè)用法來(lái)證明Python文件指針。
f = open('lyricsback','r+' ,encoding='utf-8') print(f.tell()) #this number is 0 f.seek(12) # 將指針向后面移動(dòng)幾個(gè)字節(jié),一個(gè)漢字是三個(gè)字節(jié) print(f.tell()) # this is seek number f.write("Love Girl") #這里就從seek到地方替換 print(f.tell()) # tell()用法就是文件的指針位置 f.close()
2.2、加b的方式對(duì)文件進(jìn)行操作
rb:將文件以二進(jìn)制的方式從硬盤中讀取出來(lái),這里得記住在open()函數(shù)中不要加encoding= 這個(gè)參數(shù)因?yàn)槎M(jìn)制不存在編碼上的問(wèn)題
wb:將文件以二進(jìn)制的方式寫(xiě)入內(nèi)容,不過(guò)在f.write()中加上encode="utf-8",意思就是申明編碼的格式,并且會(huì)清楚原來(lái)文件內(nèi)容
ab:只能以二進(jìn)制方式追加。
三、函數(shù)
什么是函數(shù)?函數(shù)可以簡(jiǎn)單理解一段命令的集合。為什么需要用函數(shù)?這里有一個(gè)非常簡(jiǎn)單的原因,比如說(shuō)你需要對(duì)一段代碼反復(fù)進(jìn)行操作,這里你當(dāng)然可以一直復(fù)制再粘貼,但是這樣靈活性和日后的維護(hù)成本將會(huì)變大。
#比方說(shuō)現(xiàn)在需要寫(xiě)一個(gè)報(bào)警(調(diào)用接口)的程序,這里就用監(jiān)控做比喻 if cpu > 80%: 連接郵箱服務(wù)器 發(fā)送消息 關(guān)閉連接 if memery > 80%: 連接郵箱服務(wù)器 發(fā)送消息 關(guān)閉連接 if disk > 80% 連接郵箱服務(wù)器 發(fā)送消息 關(guān)閉連接 #通過(guò)寫(xiě)這樣的一個(gè)程序我們發(fā)現(xiàn)我們一直在重復(fù)調(diào)用發(fā)送郵箱的這一套接口。這樣我們是否能想出一個(gè)辦法解決這樣的重復(fù)操作呢?請(qǐng)看下一個(gè)版本 發(fā)送郵件(): l連接郵箱服務(wù)器 發(fā)送連接 關(guān)閉連接 if cpu > 80% 發(fā)送郵件() if memery > 80%: 發(fā)送郵件() ....... # 這樣以此類推,我們只需要挑用發(fā)送郵件的這個(gè)接口就可以節(jié)省代碼的發(fā)送郵件了
通過(guò)上面的代碼我們發(fā)現(xiàn),我們只需要將報(bào)警的這一套流程放到一個(gè)公共的地方,等下面觸發(fā)報(bào)警的條件的時(shí)候調(diào)用報(bào)警的函數(shù),這樣我們就可以省去當(dāng)每次觸發(fā)報(bào)警的時(shí)候我們自己在寫(xiě)報(bào)警的步驟了。但是函數(shù)是怎么定義呢?又有什么語(yǔ)法和定義呢?請(qǐng)看下面的一段代碼,其中代碼輸出的是“Leon Have A Dream”
def leon(): #leon是函數(shù)名字 print("Leon Have A Dream") leon() #調(diào)用函數(shù)
帶參數(shù)的函數(shù):
a = 10 b = 5 def calc(a,b): print(a ** b) c = calc(a,b) print(c)
首先上面這些代碼執(zhí)行完會(huì)輸出兩個(gè)字符,一個(gè)是10000,一個(gè)是None,為什么會(huì)這樣呢?首先c是等于執(zhí)行了一遍calc這個(gè)函數(shù),所以輸出10000這個(gè)數(shù)字是肯定的,但是為什么還會(huì)輸出一個(gè)None呢?原來(lái)我們的“c”執(zhí)行了儀表calc函數(shù),而calc函數(shù)中沒(méi)有任何的返回值,所以c == None 。
PS:函數(shù)的返回結(jié)果就是return,其中return的含義就是:把函數(shù)的執(zhí)行結(jié)果返回給外面,從而讓挑用函數(shù)的“對(duì)象”得到執(zhí)行結(jié)果
下面我們?cè)诳磁c之相似的列子
a = 10 b = 5 def calc(a,b): print(a ** b) return a + b c = calc(a,b) c = calc(10,6) print(c)
首先會(huì)輸出的有三個(gè)值,分別是100000,1000000,16,為什么會(huì)是這三個(gè)呢,下面用一副圖來(lái)說(shuō)一下
PS:
形參變量只有在被調(diào)用時(shí)才分配內(nèi)存單元,在調(diào)用結(jié)束時(shí),即刻釋放所分配的內(nèi)存單元。因此,形參只在函數(shù)內(nèi)部有效。函數(shù)調(diào)用結(jié)束返回主調(diào)用函數(shù)后則不能再使用該形參變量
實(shí)參可以是常量、變量、表達(dá)式、函數(shù)等,無(wú)論實(shí)參是何種類型的量,在進(jìn)行函數(shù)調(diào)用時(shí),它們都必須有確定的值,以便把這些值傳送給形參。因此應(yīng)預(yù)先用賦值,輸入等辦法使參數(shù)獲得確定值
Python中的全局變量和局部變量
PS:函數(shù)內(nèi)部是可以修改列表,字典,集合,實(shí)例(class),我們通過(guò)下面一個(gè)圖來(lái)說(shuō)明
為什么列表和字典等會(huì)被添加和修改呢,原來(lái)函數(shù)內(nèi)部知識(shí)引用了字典和列表的內(nèi)存地址,而內(nèi)存地址無(wú)法修改(可以重新開(kāi)辟一塊內(nèi)存地址),而每個(gè)字典和列表中的每一個(gè)值都有對(duì)應(yīng)的內(nèi)存地址,但是記住我們函數(shù)是引用的列表或者字典本身的內(nèi)存地址,所以這樣打印到出來(lái)的也就會(huì)跟著改變了。
全局與局部變量
在子程序中定義的變量稱為局部變量,在程序的一開(kāi)始定義的變量稱為全局變量。
全局變量作用域是整個(gè)程序,局部變量作用域是定義該變量的子程序。
當(dāng)全局變量與局部變量同名時(shí):
在定義局部變量的子程序內(nèi),局部變量起作用;在其它地方全局變量起作用。
位置參數(shù):
像上面這樣實(shí)參和形參一一對(duì)應(yīng)的上就是就是位置參數(shù)
默認(rèn)參數(shù):
在函數(shù)將一個(gè)位置參數(shù)設(shè)置成一個(gè)默認(rèn)的值的那一個(gè)變量就是默認(rèn)參數(shù),記住默認(rèn)參數(shù)得在位置參數(shù)得后面
關(guān)鍵參數(shù):
像上面這樣實(shí)參和形參不一一對(duì)應(yīng),并且在調(diào)用函數(shù)的時(shí)候給參數(shù)賦值的叫做關(guān)鍵參數(shù)
非固定函數(shù):
通過(guò)輸出結(jié)果我們發(fā)現(xiàn)*args是接收多余的字符串類型的參數(shù),而想Python="simple"(字典)類型的會(huì)傳入給**kwargs,這就是非固定參數(shù);當(dāng)你不知道這個(gè)參數(shù)需要多少個(gè)參數(shù)時(shí)可以使用該函數(shù)類型
遞歸函數(shù)——二分查找
a = [1,2,3,4,5,7,9,10,11,12,14,15,16,17,19,21] def calc(num,find_num): print(num) mid = int(len(num) / 2) if mid == 0: if num[mid] == find_num: print("find it %s"%find_num) else: print("cannt find num") if num[mid] == find_num: print("find_num %s"%find_num) elif num[mid] > find_num: calc(num[0:mid],find_num) elif num[mid] < find_num: calc(num[mid+1:],find_num) calc(a,12)
遞歸的特性
函數(shù)必須有明確的結(jié)束(判斷)條件,也就是上圖一開(kāi)始的mid[0] 不能等于0,因?yàn)檫@樣就會(huì)沒(méi)有意義了
每次進(jìn)入更深一層遞歸時(shí),問(wèn)題規(guī)模相比上次遞歸都應(yīng)有所減少
遞歸函數(shù)每次向下遞歸一次,上次的函數(shù)占用的內(nèi)存地址不會(huì)被釋放,而是一直會(huì)被阻塞主,等待函數(shù)全部執(zhí)行完畢后釋放,所以也可以說(shuō)遞歸是相當(dāng)消耗內(nèi)存空間的,對(duì)此Python有遞歸的深度,如果超過(guò)該深度函數(shù)將會(huì)被推出(棧溢出)
匿名函數(shù):
calc = lambda x:x+2 # x是形參,冒號(hào)后的內(nèi)容是該匿名函數(shù)執(zhí)行的動(dòng)作 print(calc(5)) #匿名函數(shù)意識(shí)需要通過(guò)調(diào)用來(lái)執(zhí)行的 calc = lambda x,y,z:x*y*z #匿名函數(shù)可以傳入多個(gè)形參,各個(gè)參數(shù)之間用逗號(hào)隔開(kāi) print(calc(2,4,6)) c = map(lambda x:x*2,[2,5,4,6]) #map方法需要 傳入兩個(gè)參數(shù)一個(gè)是function(函數(shù)),itrables(可迭代)的數(shù)據(jù)類型 for i in c: print(i) #三元運(yùn)算 for i in map(lambda x:x**2 if x >5 else x - 1,[1,2,3,5,7,8,9]): #lambda最多支持三元運(yùn)算,map是直接調(diào)用匿名函數(shù),但是如果想打印map的內(nèi)容,需要循環(huán) print(i)
高階函數(shù):
def calc(x,y,f): print(f(x) + f(y)) calc(10,-10,abs)
高階函數(shù)的特性
把一個(gè)函數(shù)的內(nèi)存地址傳給另外一個(gè)函數(shù),當(dāng)做參數(shù)
一個(gè)函數(shù)把另外一個(gè)函數(shù)的當(dāng)做返回值返回
滿足上面的這個(gè)兩個(gè)特性中的一個(gè)就可以稱為高階函數(shù),這里因?yàn)橥祽?,就是直接調(diào)用了Python中的內(nèi)置函數(shù)
以上這篇Python字符編碼與函數(shù)的基本使用方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python3.6安裝及引入Requests庫(kù)的實(shí)現(xiàn)方法
下面小編就為大家分享一篇Python3.6安裝及引入Requests庫(kù)的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01PyQt子線程處理業(yè)務(wù)事件的問(wèn)題解決
在PyQt中,主線程通常是指GUI主循環(huán)所在的線程,而子線程則是執(zhí)行實(shí)際工作的線程,本文主要介紹了PyQt子線程處理業(yè)務(wù)事件的問(wèn)題解決,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02Python模擬伯努利試驗(yàn)和二項(xiàng)分布代碼實(shí)例
這篇文章主要介紹了Python模擬伯努利試驗(yàn)和二項(xiàng)分布代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05python中l(wèi)ogging庫(kù)的使用總結(jié)
Python的logging模塊提供了通用的日志系統(tǒng),可以方便第三方模塊或者是應(yīng)用使用,下面這篇文章主要給大家介紹了關(guān)于python中l(wèi)ogging庫(kù)使用的一些知識(shí)總結(jié),文中給出了詳細(xì)的示例代碼,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-10-10python 快速把超大txt文件轉(zhuǎn)存為csv的實(shí)例
今天小編就為大家分享一篇python 快速把超大txt文件轉(zhuǎn)存為csv的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10python opencv實(shí)現(xiàn)信用卡的數(shù)字識(shí)別
這篇文章主要介紹了python opencv實(shí)現(xiàn)信用卡的數(shù)字識(shí)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01