python字串編碼及亂碼解決方案 - 程式人生

文章推薦指數: 80 %
投票人數:10人

Note: 不能直接輸出decode結果:u = s.decode("utf-8"); print u; 要encode後輸出。

但是事實情況要比這個複雜,比如看如下程式碼:. 1 s = ... 程式人生>>python字串編碼及亂碼解決方案 python字串編碼及亂碼解決方案 阿新••發佈:2019-01-17 字元編碼詳解Python原始碼的編碼方式str與位元組碼s="人生苦短".s是個字串,它本身儲存的就是位元組碼(這個s可能是檔案中的一行,或者命令列中的一行?)。

那麼這個位元組碼是什麼格式的?如果這段程式碼是在直譯器上輸入的,那麼這個s的格式就是直譯器的編碼格式,對於windows的cmd而言,就是gbk。

如果將段程式碼是儲存後才執行的,比如儲存為utf-8,那麼在直譯器載入這段程式的時候,就會將s初始化為utf-8編碼。

unicode與str我們知道unicode是一種編碼標準,具體的實現標準可能是utf-8,utf-16,gbk......python在內部使用兩個位元組來儲存一個unicode,使用unicode物件而不是str的好處,就是unicode方便於跨平臺。

你可以用如下兩種方式定義一個unicode:(在python2中)1s1=u"人生苦短" 2s2=unicode("人生苦短","utf-8")python3字串實際就是用的unicode,直接s="人生苦短"py3定義bytes使用sb=b'dfja'python2.x和3.x中的字串編碼區別2.x中字串有str和unicode兩種型別,str有各種編碼區別,unicode是沒有編碼的標準形式。

unicode通過編碼轉化成str,str通過解碼轉化成unicode。

3.x中將字串和位元組序列做了區別,字串str是字串標準形式與2.x中unicode類似,bytes類似2.x中的str有各種編碼區別。

bytes通過解碼轉化成str,str通過編碼轉化成bytes。

2.x中可以檢視unicode位元組序列,3.x中不能。

Python2:Python2的原始碼.py檔案預設的編碼方式為ASCII如果想使用一種不同的編碼方式來儲存Python程式碼,我們可以在每個檔案的第一行放置編碼宣告(encodingdeclaration)。

以下宣告定義.py檔案使用windows-1252編碼方式:#-*-coding:windows-1252-*-Note:1.從技術上說,字元編碼的過載宣告也可以放在第二行,如果第一行被類UNIX系統中的hash-bang命令佔用了。

2.瞭解更多資訊,請參閱PEP263:指定Python原始碼的編碼方式。

Python3:Python3的原始碼.py檔案的預設編碼方式為UTF-8Python3.x中的Unicode在Python3.0之後的版本中,所有的字串都是使用Unicode編碼的字串序列,同時還有以下幾個改進:1、預設編碼格式改為unicode2、所有的Python內建模組都支援unicode3、不再支援u中文的語法格式所以,對於Python3.x來說,編碼問題已經不再是個大的問題,基本上很少遇到編碼異常。

在Python3,所有的字串都是使用Unicode編碼的字元序列。

不再存在以UTF-8或者CP-1252編碼的情況。

也就是說,這個字串是以UTF-8編碼的嗎?不再是一個有效問題。

UTF-8是一種將字元編碼成位元組序列的方式。

如果需要將字串轉換成特定編碼的位元組序列,Python3可以為你做到。

如果需要將一個位元組序列轉換成字串,Python3也能為你做到。

位元組即位元組,並非字元。

字元在計算機內只是一種抽象。

字串則是一種抽象的序列。

>>>s="深入Python" >>>len(s) 9 >>>s[0] "深" >>>s+"3" "深入Python3"Python中,字串可以想像成由字元組成的元組。

Justlikegettingindividualitemsoutofalist,youcangetindividualcharactersoutofastringusingindexnotation.與取得列表中的元素一樣,也可以通過下標記號取得字串中的某個字元。

python中設定預設編碼defaultencoding設定defaultencoding的程式碼如下:1reload(sys) 2sys.setdefaultencoding('utf-8')如果你在python中進行編碼和解碼的時候,不指定編碼方式,那麼python就會使用defaultencoding。

比如上一節例子中將str編碼為另一種格式,就會使用defaultencoding。

s.encode("utf-8")等價於s.decode(defaultencoding).encode("utf-8")Note:這個過程是s先通過defaultencoding解碼為unicode,再編碼為utf-8型別的編碼。

再比如你使用str建立unicode物件時,如果不說明這個str的編碼格式,那麼程式也會使用defaultencoding。

u=unicode("人生苦短")等價於u=unicode("人生苦短",defaultencoding)預設的defaultcodingascii是許多錯誤的原因,所以早早的設定defaultencoding是一個好習慣。

檔案頭宣告編碼關於python檔案頭部分知識的講解頂部的:#-*-coding:utf-8-*-或者#coding:utf-8目前有三個作用如果程式碼中有中文註釋,就需要此宣告。

比較高階的編輯器(比如我的emacs),會根據頭部宣告,將此作為程式碼檔案的格式。

程式會通過頭部宣告,解碼初始化u"人生苦短",這樣的unicode物件,(所以頭部宣告和程式碼的儲存格式要一致)。

Example1#-*-coding:utf-8-*- su="人生苦短"#su是一個utf-8格式的位元組串 u=s.decode("utf-8")#s被解碼為unicode物件,賦給u sg=u.encode("gbk")#u被編碼為gbk格式的位元組串,賦給sg printsgNote:不能直接輸出decode結果:u=s.decode("utf-8");printu;要encode後輸出。

但是事實情況要比這個複雜,比如看如下程式碼:1s="人生苦短" 2s.encode('gbk')看!str也能編碼,(事實上unicode物件也能解碼,但是意義不大)Note:原理,當對str進行編碼時,會先用預設編碼將自己解碼為unicode,然後在將unicode編碼為你指定編碼。

這就引出了python2.x中在處理中文時,大多數出現錯誤的原因所在:python的預設編碼,defaultencoding是ascii看這個例子:1#-*-coding:utf-8-*- 2s="人生苦短" 3s.encode('gbk')上面的程式碼會報錯,錯誤資訊:UnicodeDecodeError:'ascii'codeccan'tdecodebyte......因為你沒有指定defaultencoding,所以它其實在做這樣的事情:1#-*-coding:utf-8-*- 2s="人生苦短" 3s.decode('ascii').encode('gbk')Example2python2.x示例:[python]viewplaincopyprint?>>> ss = '北京市'>>> type(ss)    >>> us = ss.decode('gbk')  >>> us  u'\u5317\u4eac\u5e02'>>> type(us)    >>> nus = u'北京市'>>> nus  u'\u5317\u4eac\u5e02'>>> ss  '\xb1\xb1\xbe\xa9\xca\xd0'>>> gbks = nus.encode('gbk')  >>> gbks  '\xb1\xb1\xbe\xa9\xca\xd0'>>> print(gbks)  北京市  >>> utfs = nus.encode('utf-8')  >>> utfs  '\xe5\x8c\x97\xe4\xba\xac\xe5\xb8\x82'>>> print(utfs)  鍖椾含甯  >>> xx = utfs.decode('utf-8')  >>> type(xx)    ss='北京市'採用終端預設的編碼形式,windows命名行視窗預設是gbk編碼,所以通過ss.decode('gbk')轉化成unicode的序列。

最後utf-8編碼的utfs輸出亂碼也是因為cmd終端是gdk編碼的。

該示例中可以看到“北京市”的三種編碼序列:unicode序列:u'\u5317\u4eac\u5e02'gbk序列:'\xb1\xb1\xbe\xa9\xca\xd0'utf-8序列:'\xe5\x8c\x97\xe4\xba\xac\xe5\xb8\x82'python3.x示例:[python]viewplaincopyprint?Python 3.4.1 (v3.4.1:c0e311e010fc, May 182014, 10:38:22) [MSC v.160032 bit (In  tel)] on win32  Type "help", "copyright", "credits"or"license"for more information.  >>> ss = '北京市'>>> type(ss)    >>> us = ss.encode('gbk')  >>> type(us)    >>> us  b'\xb1\xb1\xbe\xa9\xca\xd0'>>> utfs = ss.encode('utf-8')  >>> print(utfs)  b'\xe5\x8c\x97\xe4\xba\xac\xe5\xb8\x82'>>> type(utfs)    >>> xx = utfs.decode('utf-8')  >>> type(xx)    >>> print(xx)  北京市  >>> import urllib.parse  >>> res = urllib.parse.quote(utfs)  >>> res  '%E5%8C%97%E4%BA%AC%E5%B8%82'3.x想要檢視字串各種編碼序列,只能通過encode轉化成bytes型別,然後輸出。

str是標準形式沒辦法直接檢視其位元組序列。



通過urllib.parse.quote將位元組序列轉化成url的中文編碼形式,逆過程是unquote函式。

python編碼錯誤及解決方法字串是Python中最常用的資料型別,而且很多時候你會用到一些不屬於標準ASCII字符集的字元,這時候程式碼就很可能丟擲UnicodeDecodeError:asciicodeccantdecodebyte0xc4inposition10:ordinalnotinrange(128)異常。

這種異常在Python中很容易遇到,尤其是在Python2.x中。

字串在Python內部的表示是unicode編碼,因此,在做編碼轉換時,通常需要以unicode作為中間編碼,即先將其他編碼的字串解碼(decode)成unicode,再從unicode編碼(encode)成另一種編碼。

但是,Python2.x的預設編碼格式是ASCII,就是說,在沒有指定Python原始碼編碼格式的情況下,原始碼中的所有字元都會被預設為ASCII碼。

也因為這個根本原因,在Python2.x中經常會遇UnicodeDecodeError或者UnicodeEncodeError的異常。

Unicode為了能夠處理Unicode資料,同時相容Python某些內部模組,Python2.x中提供了Unicode這種資料型別,通過decode和encode方法可以將其它編碼和Unicode編碼相互轉化,但同時也引入了UnicodeDecodeError和UnicodeEncodeError異常。

python2常見編碼異常(幾乎都只存在於python2中)Python中常見的幾種編碼異常有SyntaxError:Non-ASCIIcharacter、UnicodeDecodeError和UnicodeEncodeError等。

1、SyntaxError:Non-ASCIIcharacter這種異常主要原因是Python原始碼檔案中有非ASCII字元,而且同時沒有宣告原始碼編碼格式,例如:s='中文'prints#丟擲異常解決:檔案頭部宣告編碼#-*-coding:utf-8-*-Python2中,如果在原始碼首行(或在指定sha-bang時的第二行)不顯式指定編碼,則無法在原始碼中出現非ASCII字元。

這是由於Python2直譯器預設將原始碼認作ASCII編碼格式。

[PEP263]2、UnicodeDecodeError這個異常有時候會在呼叫decode方法時出現,原因是Python打算將其他編碼的字元轉化為Unicode編碼,但是字元本身的編碼格式和decode方法傳入的編碼格式不一致,例如:#!/usr/bin/python#-*-coding:utf-8-*-s='中文's.decode('gb2312')#UnicodeDecodeError:gb2312codeccantdecodebytesinposition2-3:illegalmultibytesequenceprintsNote:上面這段程式碼中字串s的編碼格式是utf-8(#-*-coding:utf-8-*-宣告的意思是:當前.py檔案中所有的字串是utf-8編碼的),但是在使用decode方法轉化為Unicode編碼時傳入的引數是‘gb2312’,因此在轉化的時候丟擲UnicodeDecodeError異常。

還有一種情況是在encode的時候:#!/usr/bin/python#-*-coding:utf-8-*-s='中文's.encode('gb2312')#UnicodeDecodeError:asciicodeccantdecodebyte0xe4inposition0:ordinalnotinrange(128)printsNote:這裡的s是utf-8編碼的,直接使用s.encode(gb2312)實際使用了系統預設defalutencoding(ascii)來解碼,等價於s.decode(defaultencoding).encode(gb2312),而s的實際編碼與defaultencoding不同。

3、UnicodeEncodeError錯誤的使用decode和encode方法會出現這種異常,比如:使用decode方法將Unicode字串轉化的時候。

比如下面s是unicode(所以不需要再decode,而是應該encode成utf-8)。

#!/usr/bin/python#-*-coding:utf-8-*-s=u'中文's.decode('utf-8')#UnicodeEncodeError:asciicodeccantencodecharactersinposition0-1:ordinalnotinrange(128)printspython3常見編碼異常python3就基本沒有編碼異常了,只要在頭部宣告#-*-coding:utf-8-*-,python原始碼中的字元就是utf-8,不需要decodeencode。

但是,有一種情況還是會出現編碼異常,就是使用print()時:print('測試')UnicodeEncodeError:'ascii'codeccan'tencodecharacter'\uff1a'inposition**:ordinalnotinrange(128)出現這個錯誤的原因是因為print系統有它自己的編碼,在一般python3環境中,輸出時會將Unicode轉化為utf-8。

標準輸出的定義如下:sys.stdout=codecs.getwriter("utf-8")(sys.stdout.detach())檢視輸出編碼:print(sys.stdout)#或者sys.stdout.encoding <_io.textiowrappername>'encoding='ANSI_X3.4-1968'>竟然不是utf-8!解決:sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8') #或者sys.stdout=codecs.getwriter("utf-8")(sys.stdout.detach()) print(sys.stdout) <_io.textiowrappername>'encoding='utf-8'> 或者執行python的時候加上PYTHONIOENCODING=utf-8,即PYTHONIOENCODING=utf-8pythonyour_script.py這時就能正確輸出中文了。

python編碼異常解決原則1、遵循PEP0263原則,宣告編碼格式(lz推薦)在PEP0263DefiningPythonSourceCodeEncodings中提出了對Python編碼問題的最基本的解決方法:在Python原始碼檔案中宣告編碼格式,最常見的宣告方式如下:#!/usr/bin/python#-*-coding:-*-Note:其中是程式碼所需要的編碼格式,它可以是任意一種Python支援的格式,一般都會使用utf-8的編碼格式。

#-*-coding:utf-8-*-是Python檔案宣告,意思是:當前.py檔案中所有的字串是utf-8編碼的,不是讀取的檔案是用utf-8編碼讀取的!2、使用u中文替代中文(py2)str1=中文編碼str2=u中文編碼Python中有以上兩種宣告字串變數的方式,它們的主要區別是編碼格式的不同,其中,str1的編碼格式和Python檔案宣告的編碼格式一致,而str2的編碼格式則是Unicode。

如果你要宣告的字串變數中存在非ASCII的字元,那麼最好使用str2的宣告格式,這樣你就可以不需要執行decode,直接對字串進行操作,可以避免一些出現異常的情況。

Note:python3不支援u的宣告方式。

3、Reset預設編碼Python中出現這麼多編碼問題的根本原因是Python2.x的預設編碼格式是ASCII,所以你也可以通過以下的方式修改預設的編碼格式:importsyssys.setdefaultencoding(utf-8)這種方法是可以解決部分編碼問題,但是同時也會引入很多其他問題,得不償失,不建議使用這種方式。

4、終極原則:decodeearly,unicodeeverywhere,encodelate即:在輸入或者宣告字串的時候,儘早地使用decode方法將字串轉化成unicode編碼格式;然後在程式內使用字串的時候統一使用unicode格式進行處理,比如字串拼接、字串替換、獲取字串的長度等操作;最後,在輸出字串的時候(控制檯/網頁/檔案),通過encode方法將字串轉化為你所想要的編碼格式,比如utf-8等。

按照這個原則處理Python的字串,基本上可以解決所有的編碼問題(只要你的程式碼和Python環境沒有問題)。

另外還應該使用codecs模組開啟檔案內建的open函式開啟檔案時,read方法讀取的是一個str(私以為叫做位元組陣列更合適),如果讀取的是其它編碼的文字,則需要decode之後再做使用。

對於使用open函式開啟檔案之後的寫操作(多位元組編碼的字串),則需要將需要寫入的字串按照其編碼encode為一個str,如果直接寫入,則會引發如下錯誤(如果在程式碼中加入了encoding宣告,則會按照宣告的編碼格式encode後寫入):除此以外,codecs模組也提供了一個open函式,可以直接指定好編碼開啟一個文字檔案,那麼讀取到的檔案內容則直接是一個unicode字串。

對應的指定編碼後的寫入檔案,則可以直接將unicode寫到檔案中。

通過codecs.open可以避免很多編碼問題:5、升級Python2.x到3.x主要是因為Python2.x的編碼設計問題。

當然,升級到Python3.x肯定可以解決大部分因為編碼產生的異常問題。

畢竟Python3.x版本對字串這部分還是做了相當大的改進的。

原因參見前面關於python2.x和3.x的區別。

python讀取檔案編碼錯誤出現亂碼首先用notepad++等文字檢視器檢視讀取檔案的編碼,如檔案編碼為utf-8則使用utf-8編碼方式開啟{其它格式還有gbk,gb2312,ansi等等}file=open(filename,encoding='UTF-8') 基本沒有編碼錯誤,還是出現某幾個字元錯誤也可以用‘ignore’忽略掉file=open(filename,encoding='UTF-8',errors='ignore')python讀取檔案BOM字元處理在windows上使用open開啟utf-8編碼的txt檔案時開頭會有一個多餘的字元\ufeff,它叫BOM,是用來宣告編碼等資訊的,但python會把它當作文字解析。

對UTF-16,Python將BOM解碼為空字串。

然而對UTF-8,BOM被解碼為一個字元\ufeff。

如何去掉bom字元?解決修改encoding為utf-8_sig或者utf_8_sigopen('1.txt',encoding='utf_8_sig')from:http://blog.csdn.net/pipisorry/article/details/44136297http://mp.weixin.qq.com/s?__biz=MjM5NzU0MzU0Nw==&mid=204655326&idx=1&sn=cbe436b2ecf1bb7f4f11992756d407c7&from=singlemessage&isappinstalled=0#rd c程式設計語言第二版練習題5-4 «上一篇 Python資料分析讀書筆記下一篇» 相關推薦 Busybox1.17.4編譯及錯誤解決方案 2.1Makefile中新增編譯工具:#vimMakefile找到OSS_COMPILE?=修改為:CROSS_COM... python對打印出中文亂碼問題的解決方案 defcti亂碼問題的解決falseexce轉換中文亂碼rgsdel一、引入json包二、#使用json... 關於Django中JsonResponse返回中文字典編碼錯誤的解決方案 keys**kwargs技術pythodivsafe關於orderres解決方案:JsonResponse... Python編碼問題的解決方案總結 blank獲得字符集erroport使用odinoding2這裏給大家總結一下幾種會導致編碼問題的案例,並... JAVA中文編碼和中文字元長度問題和解決方案 from:http://115.47.70.85/RuanJianGongCheng/2011-04/2859.htm ... fstream類讀取UTF-8、Unicode和ANSI文字文件亂碼問題的解決方案 1、解決UTF-8型別的文字文件中文亂碼讀取(思路:將UTF-8轉成Unicode然後再轉ANSI) #include... zmap原始碼編譯安裝流程及錯誤解決方案 參考官方給出的方案在這裡,事實上針對ubuntu我們... 關於資料處理使用python時出現的各種編碼問題的解決方案 關於python中出現的各種編碼問題 首先,windows下複製檔案的絕對路徑時請絕對不要使用屬性->安全中的直接... 【Python學習筆記】出現亂碼問題之解決方案彙總 【使用notepad++&cmd】 1.無法輸出中文: importurllib2 importcookieli... Python2.x編譯器列印中文出現亂碼的三種解決方案(本人以VS2017與VSCode為例,使用其他整合開發工具的也可參考下) 本文主要介紹了三種解決方案: 解決方案一:在需要列印的中文字元前加個u,用於標識所要列印的是一個Unicode字串。

(我感覺... 搜尋 基礎教學 Mysql入門 Sql入門 Android入門 Docker入門 Go語言入門 Ruby程式入門 Python入門 Python進階 Django入門 Python爬蟲入門 最近訪問 python字串編碼及亂碼解決方案 C語言中static的作用及C語言中使用靜態函式有何好處 leetcode176:第二高的薪水 高效編輯器vim之視窗分割 C語言-輸入任意多個數字,數字間用空格隔開,然後將數字求和。

Abaqus中施加移動車輛荷載(待整理) 如何求C語言字串長度(strlen函式和sizeof關鍵字) Linux下vim的複製、貼上操作 Innovus+Lab和Lab+Guide下載地址+|+Innovus教程+-+Flow系列+-+資料準備 xkKIM上際便高人建卻廠四統深二團



請為這篇文章評分?