日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在之前的文章中,我們介紹過編碼格式的發(fā)展史。今天我們通過幾個例子,來徹底搞清楚Python3中的編碼格式原理,這樣你之后寫python腳本時碰到編碼問題,才能有章可循。

 

我們先搞清楚幾個概念:

  • 系統(tǒng)默認(rèn)編碼:指python解釋器默認(rèn)的編碼格式,在python文件頭部沒有聲明其他編碼格式時,python3默認(rèn)的編碼格式是utf-8。
  • 本地默認(rèn)編碼:操作系統(tǒng)默認(rèn)的編碼,常見的windows的默認(rèn)編碼是gbk,linux的默認(rèn)編碼是UTF-8。
  • python文件頭部聲明編碼格式:修改的是文件的默認(rèn)編碼格式,只是會影響python解釋器讀取python文件時的編碼格式,并不會改變系統(tǒng)默認(rèn)編碼和本地默認(rèn)編碼。

通過python自帶的庫,可以查看系統(tǒng)默認(rèn)編碼和本地默認(rèn)編碼

CopyPython 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>> import locale
>>> locale.getdefaultlocale()
('zh_CN', 'cp936')
>>>

注意,因?yàn)槲以趙indows系統(tǒng)的電腦上 進(jìn)行測試,所以系統(tǒng)默認(rèn)編碼返回“cp936”, 這是代碼頁(是字符編碼集的別名),而936對應(yīng)的就是gbk。如果你在linux或者mac上執(zhí)行上面的代碼,應(yīng)該會返回utf-8編碼。

其實(shí)總結(jié)來看,容易出現(xiàn)亂碼的場景,基本都與讀寫程序有關(guān),比如:讀取/寫入某個文件,或者從網(wǎng)絡(luò)流中讀取數(shù)據(jù)等,因?yàn)檫@個過程中涉及到了編碼 和解碼的過程,只要編碼和解碼的編碼格式對應(yīng)不上,就容易出現(xiàn)亂碼。下面我們舉兩個具體的例子,來驗(yàn)證下python的編碼原理,幫助你理解這個過程。注意:下面的例子都是在pycharm中寫的。

01默認(rèn)的編碼格式#

我們新建一個encode_demo.py的文件,其文件默認(rèn)的編碼格式是UTF-8(可以從pycharm右下角看到編碼格式),代碼如下:

Copy"""
 @author: asus
 @time: 2019/11/21
 @function: 驗(yàn)證編碼格式
"""
import sys, locale


def write_str_default_encode():
 s = "我是一個str"
 print(s)
 print(type(s))
 print(sys.getdefaultencoding())
 print(locale.getdefaultlocale())

 with open("utf_file", "w", encoding="utf-8") as f:
 f.write(s)
 with open("gbk_file", "w", encoding="gbk") as f:
 f.write(s)
 with open("jis_file", "w", encoding="shift-jis") as f:
 f.write(s)


if __name__ == '__main__':
 write_str_default_encode()

我們先來猜測下結(jié)果,因?yàn)槲覀儧]有聲明編碼格式,所以python解釋器默認(rèn)用UTF-8去解碼文件,因?yàn)槲募J(rèn)編碼格式就是UTF-8,所以字符串s可以正常打印。同時以UTF-8編碼格式寫文件不會出現(xiàn)亂碼,而以gbk和shift-jis(日文編碼)寫文件會出現(xiàn)亂碼(這里說明一點(diǎn),我是用pycharm直接打開生成的文件查看的,編輯器默認(rèn)編碼是UTF-8,如果在windows上用記事本打開則其默認(rèn)編碼跟隨系統(tǒng)是GBK,gbk_file和utf_file均不會出現(xiàn)亂碼,只有jis_file是亂碼),我們運(yùn)行看下結(jié)果:

Copy# 運(yùn)行結(jié)果
我是一個str
<class 'str'>
utf-8
('zh_CN', 'cp936')

# 寫文件utf_file、gbk_file、jis_file文件內(nèi)容分別是:
我是一個str
???????str
????str

和我們猜測的結(jié)果一致,下面我們做個改變,在文件頭部聲明個編碼格式,再來看看效果。

02 python頭文件聲明編碼格式#

因?yàn)樯厦嫖募ncode_demo.py的格式是UTF-8,那么我們就將其變?yōu)間bk編碼。同樣的我們先來推測下結(jié)果,在pycharm中,在python文件頭部聲明編碼為gbk后(頭部加上 # coding=gbk ),文件的編碼格式變成gbk,同時python解釋器會用gbk去解碼encode_demo.py文件,所以運(yùn)行結(jié)果應(yīng)該和用UTF-8編碼時一樣。運(yùn)行結(jié)果如下:

Copy# 運(yùn)行結(jié)果
我是一個str
<class 'str'>
utf-8
('zh_CN', 'cp936')

# 寫文件utf_file、gbk_file、jis_file文件內(nèi)容分別是:
我是一個str
???????str
????str

結(jié)果確實(shí)是一樣的,證明我們推論是正確的。接下來我們再做個嘗試,假如我們將(# coding=gbk)去掉(需要注意,在pycharm中將 # coding=gbk去掉,并不會改變文件的編碼格式,也就是說encode_demo.py還是gbk編碼),我們再運(yùn)行一次看結(jié)果:

Copy File "D:/codespace/python/pythonObject/pythonSample/basic/encodeDemo/encode_demo.py", line 4
SyntaxError: Non-UTF-8 code starting with '\xd1' in file D:/codespace/python/pythonObject/pythonSample/basic/encodeDemo/encode_demo.py on line 5, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

運(yùn)行直接報錯了,我們加個斷點(diǎn),看看具體的異常信息:

帶你徹底搞明白python3編碼原理

 

看錯誤提示是UnicodeDecodeError,python解釋器在對encode_demo.py文件解碼時,使用默認(rèn)的UTF-8編碼,但是文件本身是gbk編碼,所以當(dāng)碰到有中文沒辦法識別時,就拋出DecodeError。

03 敲黑板,劃重點(diǎn)#

python3中的str和bytes#

python3的重要特性之一就是對字符串和二進(jìn)制流做了嚴(yán)格的區(qū)分,我們聲明的字符串都是str類型,不過Str和bytes是可以相互轉(zhuǎn)換的:

Copydef str_transfor_bytes():
 s = '我是一個測試Str'
 print(type(s))
 # str 轉(zhuǎn)bytes
 b = s.encode()
 print(b)
 print(type(b))
 # bytes轉(zhuǎn)str
 c = b.decode('utf-8')
 print(c)
 print(type(c))


if __name__ == '__main__':
 str_transfor_bytes()

需要注意一點(diǎn):在調(diào)用encode()和decode()方法時,如果不傳參數(shù),則會使用python解釋器默認(rèn)的編碼格式UTF-8(如果不在python頭文件聲明編碼格式)。但是如果傳參的話,encode和decode使用的編碼格式要能對應(yīng)上。

python3默認(rèn)編碼是UTF-8?還是Unicode?#

經(jīng)常在很多文章里看到,python3的默認(rèn)編碼格式是Unicode,但是我在本文中卻一直在說python3的默認(rèn)編碼格式是UTF-8,那么哪種說法是正確的呢?其實(shí)兩種說法都對,主要得搞清楚Unicode和UTF-8的區(qū)別(之前文章有提到):

  • Unicode是一個字符集,說白了就是把各種編碼的映射關(guān)系全都整合起來,不過它是不可變長的,全部都以兩個字節(jié)或四個字節(jié)來表示,占用的內(nèi)存空間比較大。
  • UTF-8是Unicode的一種實(shí)現(xiàn)方式,主要對 Unicode 碼的數(shù)據(jù)進(jìn)行轉(zhuǎn)換,方便存儲和網(wǎng)絡(luò)傳輸 。它是可變長編碼,比如對于英文字母,它使用一個字節(jié)就可以表示。

在python3內(nèi)存中使用的字符串全都是Unicode碼,當(dāng)python解釋器解析python文件時,默認(rèn)使用UTF-8編碼。

open()方法默認(rèn)使用本地編碼#

在上面的例子中,我們往磁盤寫入文件時,都指定了編碼格式。如果不指定編碼格式,那么默認(rèn)將使用操作系統(tǒng)本地默認(rèn)的編碼格式,比如:Linux默認(rèn)是UTF-8,windows默認(rèn)是GBK。其實(shí)這也好理解,因?yàn)楹痛疟P交互,肯定要考慮操作系統(tǒng)的編碼格式。這有區(qū)別于encode()和decode()使用的是python解釋器的默認(rèn)編碼格式,千萬別搞混淆了。

總結(jié)#

不知道你看完上面的例子后,是否已經(jīng)徹底理解了python3的編碼原理。不過所有的編碼問題,都逃不過“編碼”和“解碼”兩個過程,當(dāng)你碰到編碼問題時,先確定源文件使用的編碼,再確定目標(biāo)文件需要的編碼格式,只要能匹配,一般就可以解決編碼的問題。

最后,小編想說:我是一名python開發(fā)工程師,整理了一套最新的python系統(tǒng)學(xué)習(xí)教程,想要這些資

分享到:
標(biāo)簽:編碼 python
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定