Python中文GBK編碼解決實例

http://eatsalt.blog.163.com/blog/static/879402662009420508748/html

#coding:gbk
l=['我'.decode('gbk'),'我'.decode('gbk'),'我'.decode('gbk'),'你'.decode('gbk')]
print l.count('我'.decode('gbk'))
結果:
3
若代碼改成:
#coding:gbk
l=['我','我'.decode('gbk'),'我'.decode('gbk'),'你'.decode('gbk')]
print l.count('我'.decode('gbk'))
結果:
2
codingtest.py:3: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  print l.count('我'.decode('gbk'))
========================================================
# -*- coding:gbk -*-
import sqlite3
def initdb():
    con = sqlite3.connect(":memory:")
    cur = con.cursor()
    cur.execute("create table characters(c)")
    cur.executemany("insert into characters(c) values (?)", '我是'.decode('gbk'))
    cur.execute("select * from characters")
    for i in cur.fetchall():
        print i[0].encode('gbk')
initdb()
print '誰'.decode('gbk').encode('gbk')
結果:



先decode,再encode : '誰'.decode('gbk').encode('gbk')  纔不會出亂碼!
===========================================================================
# -*- coding:gbk -*-
import sqlite3 as db
i=open("C:\\1.txt").read()
i=(i.decode('gbk'),)
con=db.connect(":memory:")
cur=con.cursor()
cur.execute("create table BWORDS(words char(10))")
cur.execute("insert into BWORDS(words) values(?)",i)
cur.execute("select words from BWORDS")
for d in cur.fetchall():
    print d[0].encode('gbk')
結果:

我是
好哈
IDE編碼設置爲GBK。從文本文件(爲ANSI格式)讀取數據爲str類型,而後第一步進行解碼gbk:decode('gbk') 成utf8,再包裝成tuple:     i=(i.decode('gbk'),)   。最後,輸出數據,還要編碼爲gbk:  d[0].encode('gbk')
代碼二:
# -*- coding:gbk -*- 
import sqlite3 as db
i=open("C:\\1.txt").readlines()
con=db.connect(":memory:")
cur=con.cursor()
cur.execute("create table BWORDS(words char(10))")
for r in i:
    cur.execute("insert into BWORDS(words) values(?)",(r.decode('gbk'),))
cur.execute("select words from BWORDS")
for d in cur.fetchall():
    print d[0].encode('gbk')
cur.execute("select count(*) from BWORDS")
for q in cur.fetchall():
    print q[0]
結果:

我是
好哈
3
====================================================================
cur.execute("select int,chinese from FREQTABLE where freq>0")
for t in cur.fetchall():
    print t[0].encode('gbk'),t[1]
  當數表中有多列時,而且某列含有中文,這時候須要將結果轉換爲gbk編碼:t[0].encode('gbk')  ,整型則無需任何轉換!
====================================================================
如下文字選自:http://hi.baidu.com/daping_zhang/blog/item/09dda71ea9d7d21f4134173e.htmlpython

x = u"中文你好"
print ssql

    運行上述代碼,Python會給出下面的錯誤提示api

SyntaxError: Non-ASCII character '\xd6' in file G:\workspace\chinese_problem\src\test.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details網絡

   說是遇到非ASCII字符了,並讓咱們參考pep-0263。PEP-0263(Python Enhancement Proposal)上面說得很清楚了,Python也意識到了國際化問題,並提出瞭解決方案。根據提案上面的要求,咱們有以下代碼eclipse

# -*- 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編輯器

    程序運行的結果以下:fetch

-------------code 1----------------
中文a我愛你
5
中文a我喜歡你
--------------code 2----------------
中文a我愛你
3
中文a我喜歡你
---------------code 3----------------
Traceback (most recent call last):
  File "G:\Downloads\eclipse\workspace\p\src\hello.py", line 16, in <module>
    print y
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)編碼

     咱們能夠看到,經過引入編碼聲明,咱們能夠正常地在使用中文了,並且在code 1和2中,控制檯也能正確的把中文打印出來。可是,很明顯,上面的代碼也反映出了很多的問題:
    一、code 1 和 2在使用print時採用了不一樣的方式,1是直接print,而2在print以前先進行編碼
    二、code 1 和 2中在一樣的字符串查找同一個字符「我」,得出的結果不同(分別是5和3)
    三、code 3 中直接打印unicode字符串 y時出現錯誤(這也是爲何code 2中要先進行編碼的緣由)spa

    爲何?爲何?咱們能夠先在腦海中模擬一下咱們使用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窗口)進行顯示。這裏有兩種狀況:    一、若字符串是通常的字符串,那麼print只需把內存中相應的字節串推送給操做系統。如例子中的code 1。     二、若是字符串是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有詳細的描述,你們能夠參考一下。

相關文章
相關標籤/搜索