摘要:在控制臺執(zhí)行命令中文,可以將解釋為命令,中文,從而到到對象。中文以上的對象其實(shí)是,即字節(jié)碼,若終端是編碼的話,那么就是用的字節(jié)碼。那么這里的是什么呢默認(rèn)是,這正是錯(cuò)誤為什么報(bào)無法用解碼的原因中文將默認(rèn)編碼改為,即可。
問題
在平時(shí)工作中,遇到了這樣的錯(cuò)誤:
UnicodeDecodeError: "ascii" codec can"t decode byte
想必大家也都碰到過,很常見 。于是決定對python的編碼做一個(gè)整理和學(xué)習(xí)。
基礎(chǔ)知識在python2.x中,有兩種數(shù)據(jù)類型,unicode和str,這兩個(gè)都是basestring的子類
>>> a = "中" >>> type(a)>>> isinstance(a,basestring) True >>> a = u"中" >>> type(a) >>> isinstance(a,basestring) True
兩者的區(qū)別,概括來講,str是字節(jié)串,由unicode經(jīng)過編碼(encode)后的字節(jié)組成的(好比與python3.x的byte);unicode是對象,才是真正意義上的字符串,由字符組成
>>> a="中文" >>> len(a) 6 >>> repr(a) ""xe4xb8xadxe6x96x87"" >>> b=u"中文" >>> len(b) 2 >>> repr(b) "u"u4e2du6587""控制臺和腳本
在linux下的python控制臺執(zhí)行以下命令,所得的結(jié)果和執(zhí)行腳本是不同的
>>> a = u"中文" >>> repr(a) "u"xe4xb8xadxe6x96x87"" >>> b = unicode("中文","utf-8")b) >>> repr(b) "u"u4e2du6587""
可以看到,u"中文"初始化的對象a不是我們所期望的,那究竟是什么原因呢?
將python看成是一根管子,管子里頭處理的中間過程都是使用unicode的。入口處,全部轉(zhuǎn)成unicode;出口處,再轉(zhuǎn)成目標(biāo)編碼(當(dāng)然,有例外,處理邏輯中要用到具體編碼的情況)。
在控制臺執(zhí)行命令a = u"中文",可以將解釋為命令,a = ‘中文’.decode(encode),從而到到unicode對象a。那么這里的encode是什么呢?對于控制臺來說,就是標(biāo)準(zhǔn)輸入,即sys.stdin.encoding
>>> sys.stdin.encoding "ISO-8859-1"
我的這邊控制臺默認(rèn)的編碼是ISO-8859-1,故a = u"中文" <=> a = "中文".decode("ISO-8859-1")
這里的"中文"是控制臺理解的,即使根據(jù)終端編碼方式編碼后的字節(jié)碼,對于utf-8編碼的終端,"中文"="xe4xb8xadxe6x96x87"
>>> a="中文".decode("ISO-8859-1") >>> repr(a) "u"xe4xb8xadxe6x96x87""
那如何修改此編碼值呢,設(shè)置為什么呢?在linux環(huán)境中設(shè)置環(huán)境變量方法如下,具體設(shè)置什么只要與終端編碼方式一直即可
export PYTHONIOENCODING=UTF-8總結(jié)
重新回到最初的那個(gè)問題,造成問題的原因是沒有搞清楚unicode和str的區(qū)別,將兩者進(jìn)行了混用。
>>> a = "中文" >>> a.encode("gbk") Traceback (most recent call last): File "", line 1, in UnicodeDecodeError: "ascii" codec can"t decode byte 0xe4 in position 0: ordinal not in range(128)
以上的對象a其實(shí)是str,即字節(jié)碼,若終端是utf-8編碼的話,那么a就是用utf-8 encode的字節(jié)碼。a.encode("gbk") 等價(jià)于a.decode(encoding).encode("gbk"),即先將字節(jié)碼解碼為unicode字符,然后再encode為字節(jié)碼。unicode對象作為中轉(zhuǎn)站。那么這里的encoding是什么呢?
>>> import sys >>> sys.getdefaultencoding() "ascii"
默認(rèn)是ascii,這正是錯(cuò)誤為什么報(bào)無法用ascii解碼的原因
>>> reload(sys)>>> sys.setdefaultencoding("utf-8") >>> a = "中文" >>> repr(a) ""xe4xb8xadxe6x96x87"" >>> a.encode("gbk") "xd6xd0xcexc4"
將默認(rèn)編碼改為utf-8,即可。不鼓勵對str使用encode方法,因?yàn)槠渲须[式對str進(jìn)行了解碼。decode只對str,encode只對unicode,一切decode/encode都顯示指定編碼方式。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/37739.html
摘要:最近使用處理一些網(wǎng)絡(luò)相關(guān)的問題,被相關(guān)的一系列編碼問題搞得一頭霧水。與接下來是中對于字符串的處理。中的和在中,其類型規(guī)定了底層的數(shù)據(jù)結(jié)構(gòu),是位整數(shù)串,也即跟語言中的字符串類似。這些問題在中得到解決。 最近使用 Python 2 處理一些網(wǎng)絡(luò)相關(guān)的問題,被 Unicode, String 相關(guān)的一系列編碼問題搞得一頭霧水。在這里整理一下相關(guān)的概念吧。 ASCII Unicode UTF8...
摘要:使用中文替代中文中文編碼中文編碼中有以上兩種聲明字符串變量的方式,它們的主要區(qū)別是編碼格式的不同,其中,的編碼格式和文件聲明的編碼格式一致,而的編碼格式則是。 字符串是Python中最常用的數(shù)據(jù)類型,而且很多時(shí)候你會用到一些不屬于標(biāo)準(zhǔn)ASCII字符集的字符,這時(shí)候代碼就很可能拋出UnicodeDecodeError: ascii codec cant decode byte 0xc4 ...
摘要:根據(jù)有效范圍作用域分為全局變量和局部變量。類型以開頭標(biāo)識類型以開頭標(biāo)識類型以進(jìn)制的字節(jié)碼表示,實(shí)際上是一個(gè)字節(jié)串,回應(yīng)了它的另一個(gè)名字。 < 返回索引頁 基本語法 Hello World 代碼注釋 關(guān)鍵字 數(shù)據(jù)類型 變量、常量 變量 變量賦值 變量命名 變量的作用域 常量 字符串與編碼 字符轉(zhuǎn)義 字符編碼 字符串操作 運(yùn)算符與表達(dá)式 運(yùn)算符 表達(dá)式 ...
摘要:之痛原文地址譯者校正實(shí)用編程指南這是我在所做的演講。事實(shí)一和二共同造成了計(jì)算機(jī)設(shè)備結(jié)構(gòu)與世界人類需求的一個(gè)沖突。就是為了解決之前的老的字符集問題。值意味著,失敗時(shí)將會返回一個(gè)標(biāo)準(zhǔn)的替代字符。將使用進(jìn)行了解碼。 Unicode之痛原文地址: http://nedbatchelder.com/text...譯者: yudun1989 校正: sicklife實(shí)用Unicode編程指南這是...
摘要:值得注意的是,有的編碼方案不一定能表示某些信息,這時(shí)編碼就會失敗,比如就不能用來表示中文。數(shù)組的每一項(xiàng)是一個(gè)字節(jié),用來表示。所以對于字符串來說,其長度等于編碼后字節(jié)的長度。所以,讓來編碼解碼中文,就超出了其能力范圍。 在人機(jī)交互之字符編碼 一文中對字符編碼進(jìn)行了詳細(xì)的討論,并通過一些簡單的小程序驗(yàn)證了我們對于字符編碼的認(rèn)識。但僅了解這篇文章的內(nèi)容,并不能幫我們在日常編程中躲過一些字符編...
摘要:常見的字符編碼有編碼,編碼,編碼等。碼只規(guī)定了個(gè)字符的編碼,這在美國是夠用的。小結(jié)是一種針對的可變長度字符編碼,它是的實(shí)現(xiàn)方式之一。 字符編碼是計(jì)算機(jī)編程中不可回避的問題,不管你用 Python2 還是 Python3,亦或是 C++, Java 等,我都覺得非常有必要厘清計(jì)算機(jī)中的字符編碼概念。本文主要分以下幾個(gè)部分介紹: 基本概念 常見字符編碼簡介 Python 的默認(rèn)編碼 Py...
閱讀 3622·2021-09-24 09:48
閱讀 1136·2021-09-10 10:51
閱讀 3309·2019-08-30 13:03
閱讀 3362·2019-08-30 12:51
閱讀 1419·2019-08-30 11:22
閱讀 1103·2019-08-29 18:38
閱讀 2077·2019-08-29 16:41
閱讀 3271·2019-08-29 15:32