摘要:使用中文替代中文中文編碼中文編碼中有以上兩種聲明字符串變量的方式,它們的主要區別是編碼格式的不同,其中,的編碼格式和文件聲明的編碼格式一致,而的編碼格式則是。
字符串是Python中最常用的數據類型,而且很多時候你會用到一些不屬于標準ASCII字符集的字符,這時候代碼就很可能拋出UnicodeDecodeError: "ascii" codec can"t decode byte 0xc4 in position 10: ordinal not in range(128)異常。這種異常在Python中很容易遇到,尤其是在Python2.x中,是一個很讓初學者費解頭疼的問題。不過,如果你理解了Python的Unicode,并在編碼中遵循一定的原則,這種編碼問題還是比較容易理解和解決的。
字符串在Python內部的表示是unicode編碼,因此,在做編碼轉換時,通常需要以unicode作為中間編碼,即先將其他編碼的字符串解碼(decode)成unicode,再從unicode編碼(encode)成另一種編碼。但是,Python 2.x的默認編碼格式是ASCII,就是說,在沒有指定Python源碼編碼格式的情況下,源碼中的所有字符都會被默認為ASCII碼。也因為這個根本原因,在Python 2.x中經常會遇到UnicodeDecodeError或者UnicodeEncodeError的異常。
關于UnicodeUnicode是一種字符集,它為每一種現代或古代使用的文字系統中出現的每一個字符都提供了統一的序列號,規定了符號的二進制代碼,但沒有規定這個二進制代碼應該如何存儲。也就是說:Unicode的編碼方式是固定的,但是實現方式根據不同的需要有跟多種,常見的有UTF-8、UTF-16和UTF-32等。
為了能夠處理Unicode數據,同時兼容Python某些內部模塊,Python 2.x中提供了Unicode這種數據類型,通過decode和encode方法可以將其它編碼和Unicode編碼相互轉化,但同時也引入了UnicodeDecodeError和UnicodeEncodeError異常。。
常見的幾種編碼異常Python中常見的幾種編碼異常有SyntaxError: Non-ASCII character、UnicodeDecodeError和UnicodeEncodeError等。下面依次舉例說明一下:
1、SyntaxError: Non-ASCII character這種異常最不容易出現,也最容易處理,主要原因是Python源碼文件中有非ASCII字符,而且同時沒有聲明源碼編碼格式,例如:
s = "中文" print s # 拋出異常2、UnicodeDecodeError
這個異常有時候會在調用decode方法時出現,原因是Python打算將其他編碼的字符轉化為Unicode編碼,但是字符本身的編碼格式和decode方法傳入的編碼格式不一致,例如:
#!/usr/bin/python # -*- coding: utf-8 -*- s = "中文" s.decode("gb2312") # UnicodeDecodeError: "gb2312" codec can"t decode bytes in position 2-3: illegal multibyte sequence print s
上面這段代碼中字符串s的編碼格式是utf-8,但是在使用decode方法轉化為Unicode編碼時傳入的參數是‘gb2312’,因此在轉化的時候拋出UnicodeDecodeError異常。還有一種情況是在encode的時候:
#!/usr/bin/python # -*- coding: utf-8 -*- s = "中文" s.encode("gb2312") # UnicodeDecodeError: "ascii" codec can"t decode byte 0xe4 in position 0: ordinal not in range(128) print s3、UnicodeEncodeError
錯誤的使用decode和encode方法會出現這種異常,比如:使用decode方法將Unicode字符串轉化的時候:
#!/usr/bin/python # -*- coding: utf-8 -*- s = u"中文" s.decode("utf-8") # UnicodeEncodeError: "ascii" codec can"t encode characters in position 0-1: ordinal not in range(128) print s
當然,除了上面列出的幾種出現異常的情況之外還有很多可能出現異常的例子,這里就不在一一說明了。
解決方法對于以上的幾個異常,有以下幾個處理的方法和原則。
1、遵循PEP0263原則,聲明編碼格式在PEP 0263 -- Defining Python Source Code Encodings中提出了對Python編碼問題的最基本的解決方法:在Python源碼文件中聲明編碼格式,最常見的聲明方式如下:
#!/usr/bin/python # -*- coding:-*-
其中是代碼所需要的編碼格式,它可以是任意一種Python支持的格式,一般都會使用utf-8的編碼格式。
2、使用 u"中文" 替代 "中文"str1 = "中文編碼" str2 = u"中文編碼"
Python中有以上兩種聲明字符串變量的方式,它們的主要區別是編碼格式的不同,其中,str1的編碼格式和Python文件聲明的編碼格式一致,而str2的編碼格式則是Unicode。如果你要聲明的字符串變量中存在非ASCII的字符,那么最好使用str2的聲明格式,這樣你就可以不需要執行decode,直接對字符串進行操作,可以避免一些出現異常的情況。
3、Reset默認編碼Python中出現這么多編碼問題的根本原因是Python 2.x的默認編碼格式是ASCII,所以你也可以通過以下的方式修改默認的編碼格式:
import sys sys.setdefaultencoding("utf-8")
這種方法是可以解決部分編碼問題,但是同時也會引入很多其他問題,得不償失,不建議使用這種方式。
4、終極原則:decode early, unicode everywhere, encode late最后分享一個終極原則:decode early, unicode everywhere, encode late,即:在輸入或者聲明字符串的時候,盡早地使用decode方法將字符串轉化成unicode編碼格式;然后在程序內使用字符串的時候統一使用unicode格式進行處理,比如字符串拼接、字符串替換、獲取字符串的長度等操作;最后,在輸出字符串的時候(控制臺/網頁/文件),通過encode方法將字符串轉化為你所想要的編碼格式,比如utf-8等。
按照這個原則處理Python的字符串,基本上可以解決所有的編碼問題(只要你的代碼和Python環境沒有問題)。。。
5、升級Python 2.x到3.x額,最后一個方法,升級Python 2.x,使用Python 3.x版本。。這樣說主要是為了吐槽Python 2.x的編碼設計問題。當然,升級到Python 3.x肯定可以解決大部分因為編碼產生的異常問題。畢竟Python 3.x版本對字符串這部分還是做了相當大的改進的,具體的下面會說。。。。
Python 3.x中的Unicode在Python 3.0之后的版本中,所有的字符串都是使用Unicode編碼的字符串序列,同時還有以下幾個改進:
默認編碼格式改為unicode
所有的Python內置模塊都支持unicode
不再支持u"中文"的語法格式
所以,對于Python 3.x來說,編碼問題已經不再是個大的問題,基本上很少遇到上述的幾個異常。關于Python 2.x str&unicode和Python 3.x str&bytes的更多說明和對比,大家可以看一下:Python中字符編碼的總結和對比
PS: 該文章轉自我的博客:Python的中文編碼問題
Over!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/45322.html
摘要:用輸出,英文沒有問題,但是如果你輸出中文字符你好,世界就有可能會碰到中文編碼問題。實例你好,世界輸出結果為所以如果大家在學習過程中,代碼中包含中文,就需要在頭部指定編碼。注意源碼文件默認使用編碼,所以可以正常解析中文,無需指定編碼。 用 Python 輸出?Hello, World!,英文沒有問題,但是如果你輸出中文字符?你好,世界?就有可能會碰到中文編碼問題。 Python 文件中如...
摘要:在控制臺執行命令中文,可以將解釋為命令,中文,從而到到對象。中文以上的對象其實是,即字節碼,若終端是編碼的話,那么就是用的字節碼。那么這里的是什么呢默認是,這正是錯誤為什么報無法用解碼的原因中文將默認編碼改為,即可。 問題 在平時工作中,遇到了這樣的錯誤: UnicodeDecodeError: ascii codec cant decode byte 想必大家也都碰到過,很常見 。于...
摘要:中國人民看到這樣很不錯,于是就把這種漢字方案叫做。結果擴展之后的編碼方案被稱為標準,包括了的所有內容,同時又增加了近個新的漢字包括繁體字和符號。 聲明:文章借鑒自【徹底搞懂 python 中文亂碼問題】 一. 各種編碼的由來 1.1 ASCII編碼 很久很久以前,有一群人,他們決定用8個可以開合的晶體管來組合成不同的狀態,以表示世界上的萬物。他們看到8個開關狀態是好的,于是他們把這稱為...
摘要:值得注意的是,有的編碼方案不一定能表示某些信息,這時編碼就會失敗,比如就不能用來表示中文。數組的每一項是一個字節,用來表示。所以對于字符串來說,其長度等于編碼后字節的長度。所以,讓來編碼解碼中文,就超出了其能力范圍。 在人機交互之字符編碼 一文中對字符編碼進行了詳細的討論,并通過一些簡單的小程序驗證了我們對于字符編碼的認識。但僅了解這篇文章的內容,并不能幫我們在日常編程中躲過一些字符編...
摘要:編碼應運而生,編碼實際上是一個大的編碼表,他使用最少兩個字節表示一個字符的編碼方式每種語言占用了碼表的某個段,在對應的段內編碼自己的語言比如對應的編碼就是。 輸出 python 的輸出使用print 語法 print hello world //hello world //或者 print hello, world //hello world //或者 print hello w...
閱讀 3556·2023-04-25 16:35
閱讀 686·2021-10-11 11:09
閱讀 6137·2021-09-22 15:11
閱讀 3352·2019-08-30 14:03
閱讀 2590·2019-08-29 16:54
閱讀 3343·2019-08-29 16:34
閱讀 3042·2019-08-29 12:18
閱讀 2113·2019-08-28 18:31