Python3編碼問題(Python2請(qǐng)忽略)

一航缀、python程序編輯界面和運(yùn)行界面通常都是默認(rèn)unicode編碼字符串的艰山,編輯界面則是ascii編碼的涣仿,也就是程序語(yǔ)句是用ascii編碼的。但最困擾編程小白的不在這里砸琅,請(qǐng)看二宋距、

二、python的文本可以通過encode轉(zhuǎn)化為字節(jié)流bytes症脂,這時(shí)候困擾編程小白的問題來了谚赎。

(1)encode轉(zhuǎn)化后的字節(jié)流bytes是不是字符串?

答:bytes不是字符串str诱篷。在python中壶唤,bytes是字節(jié)流bytes對(duì)象,字符串是字符串str對(duì)象棕所。

(2)bytes不是字符串闸盔,那b'abc'怎么跟'abc'那么像?

答:這就不得不提一下坑爹的程序語(yǔ)言編寫者們了琳省,或者說console界面編寫者們了迎吵。注意:在運(yùn)行界面輸出bytes時(shí)候,它是采取這樣的原則的:每讀一個(gè)字節(jié)就和ascii碼比對(duì)一下针贬,如果符合ascii碼的可顯示字符(特殊字符击费,字母和數(shù)字,控制字符除外)桦他,那這個(gè)字節(jié)就按照ascii碼來表示蔫巩,否則就按十六進(jìn)制\x某某來表示。

>>> b'\x40\x41'

b'@A'

>>> b'\x00\x01'

b'\x00\x01'

這坑爹的原則不知道坑了多少迷糊的小白:怎么一會(huì)顯示一個(gè)\xff,怎么一會(huì)又顯示出一個(gè)a快压,而且看起來又是和字符串沒啥區(qū)別圆仔,搞暈了。bytes對(duì)象的顯示原則是這樣蔫劣,所以bytes對(duì)象不能包含超過0到127內(nèi)ascii碼范圍的unicode字符串坪郭,而不能接受超過這個(gè)范圍的unicode字符串。

>>> b'中'脉幢。

File "", line 1

SyntaxError: bytes can only contain ASCII literal characters.

(3)好啦截粗,那在編輯界面怎么輸入bytes信姓?

答:直接用b'字符串'表示bytes對(duì)象,這時(shí)候相當(dāng)于一個(gè)接受0到127內(nèi)ascii碼范圍內(nèi)的unicode碼字符串的函數(shù)bytes(‘字符串’)绸罗。

>>> b'@&*hello'

b'@&*hello'

(4)好,如果我不用字符串表示bytes呢豆瘫?又怎么搞珊蟀?

答:直接用\x加兩位十六進(jìn)制數(shù)字表示一個(gè)字節(jié)就可以了。

>>> b'\x41\xff\x2e\97'

b'A\xff.\\97'

(5)字符串可以通過encode轉(zhuǎn)化為bytes外驱,bytes可以通過decode轉(zhuǎn)化為字符串育灸,問題又來了,不是學(xué)挖掘機(jī)哪家強(qiáng)昵宇,而是一個(gè)字符a有很多種編碼的磅崭,按哪一種轉(zhuǎn)化為bytes?bytes本身就是一串0和1的數(shù)字瓦哎,按不同方式讀可以解釋成不同的字符砸喻,又怎么搞?

答:encode(‘編碼方式’)時(shí)指定按那個(gè)編碼轉(zhuǎn)化為bytes蒋譬。反之割岛,decode(‘編碼方式’)指定按那種方式讀取字節(jié)碼(0和1構(gòu)成的數(shù)字流)。

>>> 'a'.encode('ascii')

b'a'

>>> 'a'.encode('utf-8')

b'a'

>>> 'a'.encode('gbk')

b'a'

>>> '中'.encode('gbk')

b'\xd6\xd0'

>>> '中'.encode('utf-8')

b'\xe4\xb8\xad'

(6)坑爹的問題又來了犯助,python程序編輯界面的unicode碼u'a'是字符串還是字節(jié)碼癣漆?unicode碼又怎么表示?

答:u'a'不是字節(jié)碼剂买,是字符串惠爽!坑爹啊瞬哼!換句話說u'a'和'a'是一樣一樣的婚肆!坑爹啊倒槐!

>>> type(u'a')

<class 'str'>


unicode碼再python里有兩種表示方式:

u'字符串'或者'\u四位十六進(jìn)制數(shù)'旬痹。它們是等價(jià)的,而且都是str對(duì)象讨越。注意两残,'\\u四位十六進(jìn)制數(shù)'與'\u四位十六進(jìn)制數(shù)'并不相等,'\\u四位十六進(jìn)制數(shù)'='\\’(斜杠本身是轉(zhuǎn)義字符要經(jīng)過轉(zhuǎn)義表示)+'u四位十六進(jìn)制數(shù)'把跨。

>>> print('\u0065')

e

>>> print('\\u0065')

\u0065

(7)那如果它是字符串人弓,我要轉(zhuǎn)化為unicode碼咋整?用encode指定unicode方式着逐?

答:如果需要將內(nèi)存用的unicode碼直接保存崔赌,就指定編碼方式是'unicode-escape'意蛀!

>>> '中'.encode('unicode')

Traceback (most recent call last): ?File "", line 1, inLookupError: unknown encoding: unicode

>>> '中'.encode('unicode-escape')

b'\\u4e2d'

好!如果我不指定編碼方式呢健芭,又會(huì)怎么樣县钥?

encode默認(rèn)編碼方式是!4嚷酢若贮!utf-8!

>>> '中'.encode()

b'\xe4\xb8\xad'


三痒留、python的py文件里指定編碼方式谴麦,是指指定文件里所有內(nèi)容都是按編碼方式編碼還是字符串按編碼方式編碼?

答:py文件的編碼方式是ascii碼伸头,字符串默認(rèn)編碼是unicode碼匾效,指定編碼方式是指定從硬盤讀取py文件的編碼方式。

實(shí)際上恤磷,要區(qū)分以下編碼:系統(tǒng)默認(rèn)編碼(cmd面哼,widows的txt文件),編輯界面編碼(編輯界面顯示文本的編碼)碗殷,運(yùn)行界面編碼(運(yùn)行界面顯示文本的編碼)精绎,代碼文件(py文件)編碼,讀入的文本編碼锌妻,寫出的文本編碼代乃。

(1)系統(tǒng)默認(rèn)編碼

以windows簡(jiǎn)體中文為例,系統(tǒng)默認(rèn)編碼是gbk仿粹,命令行輸入chcp查看活動(dòng)頁(yè)代碼為936搁吓。

如果將超出gbk范圍的unicode碼,寫入系統(tǒng)的txt文件吭历,報(bào)錯(cuò)堕仔!在cmd中print,報(bào)錯(cuò)晌区!

處理方式:將unicode碼encode為bytes再寫入或print摩骨。

(2)編輯界面編碼

編輯界面編碼默認(rèn)是ascii碼,也就是寫的程序語(yǔ)句默認(rèn)是ascii編碼朗若,但一旦涉及到ascii碼不能表示的恼五,就隱形轉(zhuǎn)換為系統(tǒng)默認(rèn)編碼表示,程序語(yǔ)句中的字符串默認(rèn)是unicode碼哭懈,也就是內(nèi)存中的編碼灾馒。

在py文件頭聲明文件的編碼方式:

#-*- coding:utf-8 -*-

對(duì)編輯界面的字符串沒有什么實(shí)質(zhì)上的影響的!

pycharm編輯界面是默認(rèn)utf-8的遣总。所以有時(shí)在pycharm中編輯的代碼中沒有問題的字符串睬罗,放到cmd中編輯就會(huì)出現(xiàn)問題轨功。設(shè)置在Editor->Code Style->File Ecoding->Project Ecoding。

(3)運(yùn)行界面編碼

cmd中運(yùn)行程序容达,默認(rèn)顯示文本的編碼是ascii碼古涧,一旦超出范圍就隱式轉(zhuǎn)換為系統(tǒng)編碼。

在py文件頭聲明文件的編碼方式:

#-*- coding:utf-8 -*-

對(duì)編輯界面和運(yùn)行界面的字符串也沒有什么實(shí)質(zhì)上的影響的花盐!坑爹拜锕印!指定編碼方式是告訴系統(tǒng)按照什么編碼來讀這個(gè)py文件的卒暂。

pycharm運(yùn)行界面是默認(rèn)utf-8的。所以有時(shí)在pycharm中沒有問題的字符串娄帖,放到cmd中就會(huì)出現(xiàn)問題也祠。所以有時(shí)在pycharm中print沒有問題的字符串,放到cmd中print就會(huì)出現(xiàn)問題近速。設(shè)置在Editor->Code Style->File Ecoding->IDE Ecoding诈嘿。

(4)代碼文件編碼

代碼文件(py文件)本身也是一個(gè)文本,它也需要在硬盤或者其他載體上保存削葱,默認(rèn)編碼是系統(tǒng)編碼奖亚。這樣的話,一旦py文件copy到不同平臺(tái)析砸,問題就會(huì)發(fā)生昔字,出現(xiàn)亂碼。

特別注意:

在py文件頭聲明文件的編碼方式:

#-*- coding:utf-8 -*-

只是告訴python編譯器在讀取代碼文件時(shí)按utf-8方式讀取首繁,但這個(gè)聲明不能將py文件保存成utf-8格式的作郭!

處理方式:

py文件要多平臺(tái)運(yùn)行,最好統(tǒng)一采用一個(gè)編碼方式(如‘utf-8’)編輯和保存弦疮。

(5)讀入文件編碼

當(dāng)從網(wǎng)絡(luò)或者硬盤讀入文件的時(shí)候夹攒,實(shí)質(zhì)上讀到的是字節(jié)流:

硬盤讀入文件的默認(rèn)編碼方式是系統(tǒng)編碼方式,當(dāng)出現(xiàn)超過gbk范圍的字節(jié)出現(xiàn)胁塞,報(bào)錯(cuò)咏尝!

網(wǎng)絡(luò)讀入文件時(shí),因?yàn)樽x入的是字節(jié)啸罢,不會(huì)報(bào)錯(cuò)编检,但一旦要print時(shí)就會(huì)報(bào)錯(cuò)!

所以伺糠,如果不能按照讀入文本的編碼方式轉(zhuǎn)化為unicode蒙谓,就會(huì)出現(xiàn)問題。

處理方式:

因?yàn)閞ead()沒有編碼方式參數(shù)训桶,只能讀入bytes然后在解碼為unicode碼或者其他編碼累驮。

判斷讀入內(nèi)容的編碼方式可以用chardet的detect方法酣倾,接受一段bytes參數(shù),返回一個(gè)結(jié)果的字典谤专,里面包含編碼方式和信度區(qū)間躁锡。

withopen('/Users/liaorikun/Desktop/gbktest.txt','rb')asf:

s = f.read()

chatest = chardet.detect(s)

# print(s)

print(chatest)

檢測(cè)結(jié)果:

{'encoding': 'GB2312', 'confidence': 0.99}

(6)寫出文件編碼

寫文件編碼參看(1)

如果想將文本直接以u(píng)nicode碼保存到文件,用encode(‘unicode-escape’)轉(zhuǎn)化為bytes置侍,寫入文件映之。

如果想將文本以u(píng)tf-8形式保存到文件,用encode(‘utf-8’)轉(zhuǎn)化為utf-8編碼的bytes蜡坊,寫入文件杠输。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市秕衙,隨后出現(xiàn)的幾起案子蠢甲,更是在濱河造成了極大的恐慌,老刑警劉巖据忘,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹦牛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡勇吊,警方通過查閱死者的電腦和手機(jī)曼追,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汉规,“玉大人礼殊,你說我怎么就攤上這事■耆蹋” “怎么了膏燕?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)悟民。 經(jīng)常有香客問我坝辫,道長(zhǎng),這世上最難降的妖魔是什么射亏? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任近忙,我火速辦了婚禮,結(jié)果婚禮上智润,老公的妹妹穿的比我還像新娘及舍。我一直安慰自己,他們只是感情好窟绷,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布锯玛。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪攘残。 梳的紋絲不亂的頭發(fā)上拙友,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音歼郭,去河邊找鬼遗契。 笑死,一個(gè)胖子當(dāng)著我的面吹牛病曾,可吹牛的內(nèi)容都是我干的牍蜂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼泰涂,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鲫竞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逼蒙,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贡茅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后其做,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赁还,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年妖泄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艘策。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蹈胡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出朋蔫,到底是詐尸還是另有隱情罚渐,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布驯妄,位于F島的核電站荷并,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏青扔。R本人自食惡果不足惜源织,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望微猖。 院中可真熱鬧谈息,春花似錦、人聲如沸凛剥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)犁珠。三九已至逻炊,卻和暖如春互亮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗅骄。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工胳挎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人溺森。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓慕爬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親屏积。 傳聞我的和親對(duì)象是個(gè)殘疾皇子医窿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容