日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

在Python中關于中文編碼問題的處理建議

系統(tǒng) 1670 0

字符串是Python中最常用的數(shù)據(jù)類型,而且很多時候你會用到一些不屬于標準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的異常。

關于Unicode

Unicode是一種字符集,它為每一種現(xiàn)代或古代使用的文字系統(tǒng)中出現(xiàn)的每一個字符都提供了統(tǒng)一的序列號,規(guī)定了符號的二進制代碼,但沒有規(guī)定這個二進制代碼應該如何存儲。也就是說:Unicode的編碼方式是固定的,但是實現(xiàn)方式根據(jù)不同的需要有跟多種,常見的有UTF-8、UTF-16和UTF-32等。更多的介紹大家可以參看維基百科:Unicode

為了能夠處理Unicode數(shù)據(jù),同時兼容Python某些內部模塊,Python 2.x中提供了Unicode這種數(shù)據(jù)類型,通過decode和encode方法可以將其它編碼和Unicode編碼相互轉化,但同時也引入了UnicodeDecodeError和UnicodeEncodeError異常。。

常見的幾種編碼異常

Python中常見的幾種編碼異常有SyntaxError: Non-ASCII character、UnicodeDecodeError和UnicodeEncodeError等。下面依次舉例說明一下:

1、SyntaxError: Non-ASCII character

這種異常最不容易出現(xiàn),也最容易處理,主要原因是Python源碼文件中有非ASCII字符,而且同時沒有聲明源碼編碼格式,例如:
?

            
s = '中文'
print s   # 拋出異常

          

2、UnicodeDecodeError

這個異常有時候會在調用decode方法時出現(xiàn),原因是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編碼時傳入的參數(shù)是‘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 s

          

3、UnicodeEncodeError

錯誤的使用decode和encode方法會出現(xiàn)這種異常,比如:使用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

          

當然,除了上面列出的幾種出現(xiàn)異常的情況之外還有很多可能出現(xiàn)異常的例子,這里就不在一一說明了。

解決方法

對于以上的幾個異常,有以下幾個處理的方法和原則。

1、遵循PEP0263原則,聲明編碼格式

在PEP 0263 -- Defining Python Source Code Encodings中提出了對Python編碼問題的最基本的解決方法:在Python源碼文件中聲明編碼格式,最常見的聲明方式如下:

            
#!/usr/bin/python
# -*- coding: 
            
               -*-

            
          

其中 是代碼所需要的編碼格式,它可以是任意一種Python支持的格式,一般都會使用utf-8的編碼格式。

2、使用u'中文'替代'中文'
?

            
str1 = '中文編碼'
str2 = u'中文編碼'

          

Python中有以上兩種聲明字符串變量的方式,它們的主要區(qū)別是編碼格式的不同,其中,str1的編碼格式和Python文件聲明的編碼格式一致,而str2的編碼格式則是Unicode。如果你要聲明的字符串變量中存在非ASCII的字符,那么最好使用str2的聲明格式,這樣你就可以不需要執(zhí)行decode,直接對字符串進行操作,可以避免一些出現(xiàn)異常的情況。

3、Reset默認編碼

Python中出現(xiàn)這么多編碼問題的根本原因是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編碼格式;然后在程序內使用字符串的時候統(tǒng)一使用unicode格式進行處理,比如字符串拼接、字符串替換、獲取字符串的長度等操作;最后,在輸出字符串的時候(控制臺/網頁/文件),通過encode方法將字符串轉化為你所想要的編碼格式,比如utf-8等。

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

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編碼的字符串序列,同時還有以下幾個改進:

1、默認編碼格式改為unicode

2、所有的Python內置模塊都支持unicode

3、不再支持u'中文'的語法格式

所以,對于Python 3.x來說,編碼問題已經不再是個大的問題,基本上很少遇到上述的幾個異常。關于Python 2.x str&unicode和Python 3.x str&bytes的更多說明和對比,大家可以看一下:Python中字符編碼的總結和對比


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 陕西省| 乐都县| 全椒县| 华宁县| 轮台县| 开江县| 格尔木市| 安图县| 招远市| 中方县| 宁南县| 禄丰县| 福建省| 满洲里市| 龙岩市| 阜阳市| 西城区| 易门县| 丰原市| 鹰潭市| 南溪县| 东乌| 闽侯县| 明水县| 南汇区| 德化县| 偏关县| 双峰县| 上栗县| 望谟县| 镶黄旗| 榆中县| 靖边县| 张家口市| 海门市| 泉州市| 平潭县| 北票市| 太仆寺旗| 双柏县| 宁陕县|