python中的代碼編碼格式轉換問題
剛來這個公司,熟悉了環境,老大就開始讓我做一個遷移、修改代碼的工作,我想說的是,這種工作真沒勁~~,看別人的代碼、改別人的代碼、這裡改個變數、那裡改個檔案名稱······,都是些沒技術含量、很繁瑣的事情,不過通過遷移代碼順便熟悉下環境也好。扯了這麼多,說說今天的主題吧——代碼編碼格式改變,由於某些原因,需要將代碼從A機房遷移到B機房,這兩個之間不能互相訪問,但是曆史原因導致A機房的代碼全是utf8編碼的,B機房要求是GBK編碼,看看這個怎麼解決。
編碼問題
先說說為什麼會有編碼問題,就拿上面那個例子來說,B機房這邊資料庫全是GBK編碼的,因此從資料庫中取出來的資料都是GBK的,從資料庫中取出來的資料是GBK編碼的,要在展示的時候不亂碼,在不對資料庫取出的資料轉換的情況下,就需要發送header的時候設定編碼為GBK,輸出的檔案(html、tpl等)都必須是GBK的,看看下面這個圖會更清楚點:
DB(GBK) => php等(編碼格式不限但如果代碼檔案中有漢字,檔案就要是gbk編碼或者在漢字輸出的時候轉化為gbk) => header(GBK) => html、tpl(GBK)
或者還有一種方式只在出庫的時候在代碼中將utf8轉化為gbk,總的來說utf8還是更流行點,問題更少點
DB(GBK) => php等(utf8,並將從資料庫取出的資料轉化為utf8) => header(utf8) => html、tpl(utf8)
只要按照上面這兩種規範編碼格式,就不會出現亂碼情況,起碼我測試的第一種方式是沒問題的,所以我猜第二種也ok,好了,現在就來寫一個轉換檔編碼格式的小指令碼:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#!/usr/bin/python # -*- coding: utf-8 -*- #Filename:changeEncode.py import os import sys def ChangeEncode(file,fromEncode,toEncode): try: f=open(file) s=f.read() f.close() u=s.decode(fromEncode) s=u.encode(toEncode) f=open(file,"w"); f.write(s) return 0; except: return -1; def Do(dirname,fromEncode,toEncode): for root,dirs,files in os.walk(dirname): for _file in files: _file=os.path.join(root,_file) if(ChangeEncode(_file,fromEncode,toEncode)!=0): print "[轉換失敗:]"+_file else: print "[成功:]"+_file def CheckParam(dirname,fromEncode,toEncode): encode=["UTF-8","GBK","gbk","utf-8"] if(not fromEncode in encode or not toEncode in encode): return 2 if(fromEncode==toEncode): return 3 if(not os.path.isdir(dirname)): return 1 return 0 if __name__=="__main__": error={1:"第一個參數不是一個有效檔案夾",3:"源編碼和目標編碼相同",2:"您要轉化的編碼不再範圍之內:UTF-8,GBK"} dirname=sys.argv[1] fromEncode=sys.argv[2] toEncode=sys.argv[3] ret=CheckParam(dirname,fromEncode,toEncode) if(ret!=0): print error[ret] else: Do(dirname,fromEncode,toEncode) |
指令碼很簡單,使用也很簡單
代碼如下:
./changeEncode.py target_dir fromEncode toEncode
這裡要注意下,幾種常見編碼的關係:
us-ascii編碼是utf-8編碼的一個子集,這個是從stackoverflow上得到的,原文如下ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded,
我試了下確實是的,在不加漢字的時候顯示編碼為us-ascii,加了漢字之後,變為utf-8。
還有就是ASNI編碼格式,這代表是本地編碼格式,比如說在簡體中文作業系統下,ASNI編碼就代表GBK編碼,這點還需要注意
還有一點就是一個在linux下查看檔案編碼格式的命令是:
file -i *
可以看到檔案的編碼格式。
當然了,上面的可能有些檔案中有特殊字元,處理的時候會失敗,但一般程式檔案是沒有問題的。