Python的中文識別問題解決辦法

2021-08-10 19:00:35 字數 4659 閱讀 2234

python

的中文問題解決辦法

python 

的ecli

ps教程

環境後寫了乙個測試程式。結果出現這樣的錯誤:

syntaxerror: non-ascii character 'xbd' in file e:workspacemakeupdatafilesindexsrcmakeindex.py on line 12, but no encoding declared; see for details

原因是它不能識別中文編碼。要在第一行加入   

# -*- coding: gbk -*-

python

中有兩種字串,分別是一般的字串(每個字元用8 bits表示)和

unicode

字串(每個字元用乙個或者多個位元組表示),它們可以相互轉換。

,我們先要了解

python

中有兩種字串,分別是一般的字串(每個字元用8 bits表示)和unicode字串(每個字元用乙個或者多個位元組表示),它們可以相互轉換。關於

unicode

,joel spolsky

在 the absolute minimum every software developer absolutely, positively must know about unicode and character sets (no excuses!)

中有生動的說明,

jason orendorff

在 unicode for programmers

有著更為全面的描述,在此我就不再多說什麼了。來看下面的**:

x = u

"中文你好"

print s

執行上述**,

python

會給出下面的錯誤提示

syntaxerror: non-ascii character 'xd6' in file g:workspacechinese_problemsrctest.py on line 1, but no encoding declared; see for details

說是遇到非

ascii

字元了,並讓我們參考

pep-0263

。pep-0263(python enhancement proposal)

上面說得很清楚了,

python

也意識到了國際化問題,並提出了解決方案。根據提案上面的要求,我們有如下**

# -*- coding:gb2312 -*- #

必須在第一行或者第二行

print "-------------code 1----------------"

a ="中文

a我愛你"

print a

print a.find

("我")

b = a.replace

("愛", "喜歡")

print b

print "--------------code 2----------------"

x ="中文a我愛你"

y = unicode(x, "gb2312")

print y.encode("gb2312")

print y.find(u

"我")

z = y.replace(u

"愛",

u"喜歡"

)print z.encode("gb2312")

print "---------------code 3----------------"

print y    

程式執行的結果如下:

-------------code 1----------------中文a

我愛你5

中文a我喜歡你

--------------code 2----------------中文a

我愛你3

中文a我喜歡你

---------------code 3----------------

traceback (most recent call last):

file "g:downloadseclipseworkspacepsrchello.py", line 16, in

print y

unicodeencodeerror: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

我們可以看到,通過引入編碼宣告,我們可以正常地在使用中文了,而且在

code

1和2中,控制台也能正確的把中文列印出來。但是,很明顯,上面的**也反映出了不少的問題:

1、code 1

和 2在使用

print

時採用了不同的方式,1是直接

print

,而2在

print

之前先進行編碼

2、code 1和2

中在同樣的字串查詢同乙個字元「我」,得出的結果不一樣(分別是5和3)

3、code 3

中直接列印

unicode

字串 y時出現錯誤(這也是為什麼

code 2

中要先進行編碼的原因)

為什麼?為什麼?我們可以先在腦海中模擬一下我們使用

python

的流程:首先,我們先用編輯器編寫好源**,儲存成檔案。如果源**中有編碼宣告而且用的編輯器支援該語法,那麼該檔案就以相應的編碼方式儲存在磁碟中。注意:編碼宣告和原始檔的編碼不一定是一致的,你完全可以在編碼宣告中宣告編碼為

utf-8

,但是用

gb2312

來儲存原始檔。當然,我們不可能自尋煩惱,故意寫錯,而且好的

ide也能強制保證兩者的一致性,但是,如果我們用記事本或者

editplus

等編輯器來編寫**的話,一不小心就會出現這種問題的。

得到乙個

.py檔案後,我們就可以執行它了,這是,我們就把**交給

python

解析器來完成解析工作。解析器讀入檔案時,先解析檔案中的編碼宣告,我們假設檔案的編碼為

gb2312

,那麼先將檔案中的內容由

gb2312

轉換成unicode

,然後再把這些

unicode

轉換為utf-8

格式的位元組串。完成這一步驟後,解析器把這些

utf-8

位元組串分段,解析。如果遇到使用

unicode

字串,那麼就使用相應的

utf-8

位元組串建立

unicode

字串,如果程式中使用的是一般的字串,那麼解析器先將utf-8位元組串通過

unicode

轉換成相應編碼(這裡就是

gb2312

編碼)的位元組串,並用其建立一般的字串物件。也就是說,

unicode

字串跟一般字串在記憶體中的存放格式是不一樣的,前者使用

utf-8

的格式,後者使用

gb2312

格式。好了,記憶體中的字串存放格式我們知道了,下面我們要了解

print

的工作方式。

print

其實只是負責把記憶體中相應的位元組串交給作業系統,讓作業系統相應的程式(譬如

cmd視窗)進行顯示。這裡有兩種情況:

1、若字串是一般的字串,那麼

print

只需把記憶體中相應的位元組串推送給作業系統。如例子中的

code 1

。2、如果字串是

unicode

字串,那麼

print

在推送之前先進行相應的

encode

:我們可以顯示使用

unicode

的encode

方法使用合適的編碼方式來編碼(例子中

code 2

),否則

python

使用預設的編碼方式進行編碼,也就是

ascii

(例子中的

code 3

)。當然

ascii

是不可能正確編碼中文的,因此

python

報錯。至此,上面的三個問題我們已經可以解析第一和第三個了。至於第二個問題,因為

python

中有兩種字串,一般字串和

unicode

字串,兩者都有各自的

字元處理

方法。對於前者,方法是以位元組的方式進行的,而且在

gb2312

中,每個漢字占用兩個位元組,因此得到的結果是5;對於後者,也就是

unicode

字串,所有字元都是統一看待的,因此得到3。

雖然上面只提到了控制台程式的中文問題,但是檔案讀寫以及網路傳輸中出現的中文問題在原理上都是類似的。

unicode

的出現可以很大程度上解決軟體的國際化問題,同時

python

為unicode

提供了極為良好的支援,因此,我建議大家在編寫

python

的程式時,都統一使用

unicode

方式。儲存檔案時使用

utf-8

的編碼方式。

how to use utf-8 with python

有詳細的描述,

MX5 adb 無法識別問題解決

如下過程解決問題了 1.mac 關於本機 系統報告 usb 複製 廠商id 0x2a45 2.cmd echo 0x2a45 android adb usb.ini 在我的mac上就沒有adb usb.ini檔案,自己建立 cd android touch adb usb.ini在terminal中...

opencv3人臉識別問題解決

最近實現人臉識別,由於採用的是opencv3,而opencv3的人臉識別庫等contrib模組已經不再內建了。而這個模組要用cmake進行編譯,詳情可以參考其它博主的文章 整個contrib模組是很大的,而我只想使用其中的人臉識別模組,即face,我又對cmake不太熟悉,所以我用了乙個直接匯入標頭...

MySql的中文識別問題

關於mysql的中文識別問題,一直本來想去迴避這個問題的,但是今天在做專案的時候確實用到了,這就讓我很惱火,於是,想盡了所有辦法,搞了我一晚上,終於找到了對於這個問題準確的說對我而言的解決方案。由於我是直接安裝的wampserver,不知道是版本還是什麼原因,我竟然在my.ini的檔案找不到相應的對...