python中處理中文編碼問題
阿新 • • 發佈:2019-02-19
今天在嘗試Python的CGI模組時遇到中文字元不能正確顯示的問題,很鬱悶.
在網上仔細找了找,終於解決了這個問題,現在將解決方 法陳述如下,以防下次失誤. 頁面原始碼如下 #-*- coding: utf8 -*- import cgitb , cgi
cgitb.enable() form = cgi.FieldStorage()
if (form.has_key("name") and form.has_key("addr")):
print "<p>name:", form["name"].value print "<p>addr:", form["addr"].value [這裡僅僅測試addr引數為中文]接收Ascii字元時執行良好,但是接收中文字元時顯示亂碼,
瀏覽器切換到GB2312編碼時,可 以正常顯示,但是個人要求它成為UTF-8編碼顯示 改成 print "<p>addr:", form["addr"].value.encode('utf-8') 就報如下錯誤: UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-1: invalid data Python 裡面的編碼和解碼也就是 unicode 和 str 這兩種形式的相互轉化。
編碼是 unicode -> str,相反的,解碼就 是 str -> unicode。
剩下的問題就是確定何時需要進行編碼或者解碼了.關於檔案開頭的"編碼指 示",
也就是 # -*- coding: -*- 這個語句。Python 預設指令碼檔案都是 UTF-8 編碼的,
當檔案中有非 UTF-8 編碼範圍內的字元的時候就要使用"編碼指示"來修正.
關於 sys.defaultencoding,這個在解碼沒有明確指明解碼方式的時候使用。 比如我有如下程式碼:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
s = '中文' # 注意這裡的 str 是 str 型別的,而不是 unicode
s.encode('gb18030') 這句程式碼將 s 重新編碼為 gb18030 的格式,即進行 unicode -> str 的轉換。
因為 s 本身就是 str 型別的,因此 Python 會自動的先將 s 解碼為 unicode ,
然後再編碼成 gb18030。因為解碼是python自動進行的,我們沒有指明解碼方式,
python 就會使用 sys.defaultencoding 指明的方式來解碼。
很多情況下 sys.defaultencoding 是 ANSCII,如果 s 不是這個型別就會出錯。
拿上面的 情況來說,我的 sys.defaultencoding 是 anscii,
而 s 的編碼方式和檔案的編碼方式一致,是 utf8 的,所以出錯了:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position
0: ordinal not in range(128)
對於這種情況,我們有兩種方法來改正錯誤:
一 是明確的指示出 s 的編碼方式 #! /usr/bin/env python
# -*- coding: utf-8 -*- s = '中文'
s.decode('utf-8').encode('gb18030')
二是更改 sys.defaultencoding 為檔案的編碼方式 #! /usr/bin/env python
# -*- coding: utf-8 -*- import sys
reload(sys) # Python2.5 初始化後會刪除 sys.setdefaultencoding 這個方法,我們需要重新載入
sys.setdefaultencoding('utf-8') str = '中文'
str.encode('gb18030') 看完之後,改成這樣
print "<p>addr:", form["addr"].value.decode('gb2312').encode('utf-8')
成功通過. 我總結一下為什麼要這麼寫的原因: 1. 當取回來的資料與你當前指令碼中宣告的編碼不一致時就要做編碼轉換 2.在編碼轉換時首先要將該資料以自身編碼的格式換成unicode碼,再將這個unicode按utf8編碼 3.為什麼我的瀏覽器會傳回gb2312的編碼資料到伺服器,這應該和客戶端的系統編碼有關係 這裡順便轉載一下,關於Python 操作Mysql的中文問題: Python操作MySQL以及中文亂碼的問題 下面幾個措施,保證MySQL的輸出沒有亂麻:
1 Python檔案設定編碼 utf-8 (檔案前面加上 #encoding=utf-8)
2 MySQL資料庫charset=utf-8
3 Python連線MySQL是加上引數 charset=utf8
4 設定Python的預設編碼為 utf-8 (sys.setdefaultencoding(utf-8)
Java程式碼
#encoding=utf-8
import sys
import MySQLdb
reload(sys)
sys.setdefaultencoding('utf-8')
db=MySQLdb.connect(user='root',charset='utf8')
cur=db.cursor()
cur.execute('use mydb')
cur.execute('select * from mytb limit 100')
f=file("/home/user/work/tem.txt",'w')
for i in cur.fetchall():
f.write(str(i))
f.write(" ")
f.close()
cur.close() #encoding=utf-8
import sys
import MySQLdb reload(sys)
sys.setdefaultencoding('utf-8') db=MySQLdb.connect(user='root',charset='utf8')
cur=db.cursor()
cur.execute('use mydb')
cur.execute('select * from mytb limit 100') f=file("/home/user/work/tem.txt",'w') for i in cur.fetchall():
f.write(str(i))
f.write(" ") f.close()
cur.close()
在網上仔細找了找,終於解決了這個問題,現在將解決方 法陳述如下,以防下次失誤. 頁面原始碼如下 #-*- coding: utf8 -*- import cgitb , cgi
cgitb.enable() form = cgi.FieldStorage()
if (form.has_key("name") and form.has_key("addr")):
print "<p>name:", form["name"].value print "<p>addr:", form["addr"].value [這裡僅僅測試addr引數為中文]接收Ascii字元時執行良好,但是接收中文字元時顯示亂碼,
瀏覽器切換到GB2312編碼時,可 以正常顯示,但是個人要求它成為UTF-8編碼顯示 改成 print "<p>addr:", form["addr"].value.encode('utf-8') 就報如下錯誤: UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-1: invalid data Python 裡面的編碼和解碼也就是 unicode 和 str 這兩種形式的相互轉化。
編碼是 unicode -> str,相反的,解碼就 是 str -> unicode。
剩下的問題就是確定何時需要進行編碼或者解碼了.關於檔案開頭的"編碼指 示",
也就是 # -*- coding: -*- 這個語句。Python 預設指令碼檔案都是 UTF-8 編碼的,
當檔案中有非 UTF-8 編碼範圍內的字元的時候就要使用"編碼指示"來修正.
關於 sys.defaultencoding,這個在解碼沒有明確指明解碼方式的時候使用。 比如我有如下程式碼:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
s = '中文' # 注意這裡的 str 是 str 型別的,而不是 unicode
s.encode('gb18030') 這句程式碼將 s 重新編碼為 gb18030 的格式,即進行 unicode -> str 的轉換。
因為 s 本身就是 str 型別的,因此 Python 會自動的先將 s 解碼為 unicode ,
然後再編碼成 gb18030。因為解碼是python自動進行的,我們沒有指明解碼方式,
python 就會使用 sys.defaultencoding 指明的方式來解碼。
很多情況下 sys.defaultencoding 是 ANSCII,如果 s 不是這個型別就會出錯。
拿上面的 情況來說,我的 sys.defaultencoding 是 anscii,
而 s 的編碼方式和檔案的編碼方式一致,是 utf8 的,所以出錯了:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position
0: ordinal not in range(128)
對於這種情況,我們有兩種方法來改正錯誤:
一 是明確的指示出 s 的編碼方式 #! /usr/bin/env python
# -*- coding: utf-8 -*- s = '中文'
s.decode('utf-8').encode('gb18030')
二是更改 sys.defaultencoding 為檔案的編碼方式 #! /usr/bin/env python
# -*- coding: utf-8 -*- import sys
reload(sys) # Python2.5 初始化後會刪除 sys.setdefaultencoding 這個方法,我們需要重新載入
sys.setdefaultencoding('utf-8') str = '中文'
str.encode('gb18030') 看完之後,改成這樣
print "<p>addr:", form["addr"].value.decode('gb2312').encode('utf-8')
成功通過. 我總結一下為什麼要這麼寫的原因: 1. 當取回來的資料與你當前指令碼中宣告的編碼不一致時就要做編碼轉換 2.在編碼轉換時首先要將該資料以自身編碼的格式換成unicode碼,再將這個unicode按utf8編碼 3.為什麼我的瀏覽器會傳回gb2312的編碼資料到伺服器,這應該和客戶端的系統編碼有關係 這裡順便轉載一下,關於Python 操作Mysql的中文問題: Python操作MySQL以及中文亂碼的問題 下面幾個措施,保證MySQL的輸出沒有亂麻:
1 Python檔案設定編碼 utf-8 (檔案前面加上 #encoding=utf-8)
2 MySQL資料庫charset=utf-8
3 Python連線MySQL是加上引數 charset=utf8
4 設定Python的預設編碼為 utf-8 (sys.setdefaultencoding(utf-8)
Java程式碼
#encoding=utf-8
import sys
import MySQLdb
reload(sys)
sys.setdefaultencoding('utf-8')
db=MySQLdb.connect(user='root',charset='utf8')
cur=db.cursor()
cur.execute('use mydb')
cur.execute('select * from mytb limit 100')
f=file("/home/user/work/tem.txt",'w')
for i in cur.fetchall():
f.write(str(i))
f.write(" ")
f.close()
cur.close() #encoding=utf-8
import sys
import MySQLdb reload(sys)
sys.setdefaultencoding('utf-8') db=MySQLdb.connect(user='root',charset='utf8')
cur=db.cursor()
cur.execute('use mydb')
cur.execute('select * from mytb limit 100') f=file("/home/user/work/tem.txt",'w') for i in cur.fetchall():
f.write(str(i))
f.write(" ") f.close()
cur.close()