應用Shell劇本完成長途MySQL主動查詢。本站提示廣大學習愛好者:(應用Shell劇本完成長途MySQL主動查詢)文章只能為提供參考,不一定能成為您想要的結果。以下是應用Shell劇本完成長途MySQL主動查詢正文
1. 字符編碼簡介
1.1. ASCII
ASCII(American Standard Code for Information Interchange),是一種單字節的編碼。盤算機世界裡一開端只要英文,而單字節可以表現256個分歧的字符,可以表現一切的英文字符和很多的掌握符號。不外ASCII只用到了個中的一半(\x80以下),這也是MBCS得以完成的基本。
1.2. MBCS
但是盤算機世界裡很快就有了其他說話,單字節的ASCII已沒法知足需求。後來每一個說話就制訂了一套本身的編碼,因為單字節能表現的字符太少,並且同時也須要與ASCII編碼堅持兼容,所以這些編碼紛纭應用了多字節來表現字符,如GBxxx、BIGxxx等等,他們的規矩是,假如第一個字節是\x80以下,則依然表現ASCII字符;而假如是\x80以上,則跟下一個字節一路(共兩個字節)表現一個字符,然後跳過下一個字節,持續往下斷定。
這裡,IBM創造了一個叫Code Page的概念,將這些編碼都支出囊中並分派頁碼,GBK是第936頁,也就是CP936。所以,也能夠應用CP936表現GBK。
MBCS(Multi-Byte Character Set)是這些編碼的統稱。今朝為止年夜家都是用了雙字節,所以有時刻也叫做DBCS(Double-Byte Character Set)。必需明白的是,MBCS其實不是某一種特定的編碼,Windows裡依據你設定的區域分歧,MBCS指代分歧的編碼,而Linux裡沒法應用MBCS作為編碼。在Windows中你看不到MBCS這幾個字符,由於微軟為了加倍洋氣,應用了ANSI來恫嚇人,記事本的另存為對話框裡編碼ANSI就是MBCS。同時,在簡體中文Windows默許的區域設定裡,指代GBK。
1.3. Unicode
後來,有人開端認為太多編碼招致世界變得過於龐雜了,讓人腦殼疼,因而年夜家坐在一路拍腦殼想出來一個辦法:一切說話的字符都用統一種字符集來表現,這就是Unicode。
最後的Unicode尺度UCS-2應用兩個字節表現一個字符,所以你經常可以聽到Unicode應用兩個字節表現一個字符的說法。但過了不久有人認為256*256太少了,照樣不敷用,因而湧現了UCS-4尺度,它應用4個字節表現一個字符,不外我們用的最多的依然是UCS-2。
UCS(Unicode Character Set)還僅僅是字符對應碼位的一張表罷了,好比"漢"這個字的碼位是6C49。字符詳細若何傳輸和貯存則是由UTF(UCS Transformation Format)來擔任。
一開端這事很簡略,直接應用UCS的碼位來保留,這就是UTF-16,好比,"漢"直接應用\x6C\x49保留(UTF-16-BE),或是倒過去應用\x49\x6C保留(UTF-16-LE)。但用著用著美國人認為本身吃了年夜虧,之前英文字母只須要一個字節就可以保留了,如今年夜鍋飯一吃釀成了兩個字節,空間消費年夜了一倍……因而UTF-8橫空降生。
UTF-8是一種很別扭的編碼,詳細表示在他是變長的,而且兼容ASCII,ASCII字符應用1字節表現。但是這裡省了的一定是從其余處所摳出來的,你確定也據說過UTF-8裡中文字符應用3個字節來保留吧?4個字節保留的字符更是在淚奔……(詳細UCS-2是怎樣釀成UTF-8的請自行搜刮)
別的值得一提的是BOM(Byte Order Mark)。我們在貯存文件時,文件應用的編碼並沒有保留,翻開時則須要我們記住本來保留時應用的編碼並應用這個編碼翻開,如許一來就發生了很多費事。(你能夠想說記事本翻開文件時並沒有讓選編碼?無妨先翻開記事本再應用文件 -> 翻開看看)而UTF則引入了BOM來表現本身編碼,假如一開端讀入的幾個字節是個中之一,則代表接上去要讀取的文字應用的編碼是響應的編碼:
BOM_UTF8 '\xef\xbb\xbf'
BOM_UTF16_LE '\xff\xfe'
BOM_UTF16_BE '\xfe\xff'
其實不是一切的編纂器都邑寫入BOM,但即便沒有BOM,Unicode照樣可以讀取的,只是像MBCS的編碼一樣,須要另行指定詳細的編碼,不然解碼將會掉敗。
你能夠據說過UTF-8不須要BOM,這類說法是纰謬的,只是絕年夜多半編纂器在沒有BOM時都是以UTF-8作為默許編碼讀取。即便是保留時默許應用ANSI(MBCS)的記事本,在讀取文件時也是先應用UTF-8測試編碼,假如可以勝利解碼,則應用UTF-8解碼。記事本這個體扭的做法形成了一個BUG:假如你新建文本文件並輸出"姹塧"然後應用ANSI(MBCS)保留,再翻開就會釀成"漢a",你無妨嘗嘗 :)
2. Python2.x中的編碼成績
2.1. str和unicode
str和unicode都是basestring的子類。嚴厲意義上說,str實際上是字節串,它是unicode經由編碼後的字節構成的序列。對UTF-8編碼的str'漢'應用len()函數時,成果是3,由於現實上,UTF-8編碼的'漢' == '\xE6\xB1\x89'。
unicode才是真正意義上的字符串,對字節串str應用准確的字符編碼停止解碼後取得,而且len(u'漢') == 1。
再來看看encode()和decode()兩個basestring的實例辦法,懂得了str和unicode的差別後,這兩個辦法就不會再混雜了:
# coding: UTF-8
u = u'漢'
print repr(u) # u'\u6c49'
s = u.encode('UTF-8')
print repr(s) # '\xe6\xb1\x89'
u2 = s.decode('UTF-8')
print repr(u2) # u'\u6c49'
# 對unicode停止解碼是毛病的
# s2 = u.decode('UTF-8')
# 異樣,對str停止編碼也是毛病的
# u2 = s.encode('UTF-8')
須要留意的是,固然對str挪用encode()辦法是毛病的,但現實上Python不會拋出異常,而是前往別的一個雷同內容但分歧id的str;對unicode挪用decode()辦法也是如許。很不睬解為何不把encode()和decode()分離放在unicode和str中而是都放在basestring中,但既然曾經如許了,我們就當心防止出錯吧。
2.2. 字符編碼聲明
源代碼文件中,假如有效到非ASCII字符,則須要在文件頭部停止字符編碼的聲明,以下:
#-*- coding: UTF-8 -*-
現實上Python只檢討#、coding和編碼字符串,其他的字符都是為了雅觀加上的。別的,Python中可用的字符編碼有許多,而且還有很多別號,還不辨別年夜小寫,好比UTF-8可以寫成u8。拜見http://docs.python.org/library/codecs.html#standard-encodings。
別的須要留意的是聲明的編碼必需與文件現實保留時用的編碼分歧,不然很年夜概率會湧現代碼解析異常。如今的IDE普通會主動處置這類情形,轉變聲明後同時換成聲明的編碼保留,但文本編纂器控們須要當心 :)
2.3. 讀寫文件
內置的open()辦法翻開文件時,read()讀取的是str,讀取後須要應用准確的編碼格局停止decode()。write()寫入時,假如參數是unicode,則須要應用你願望寫入的編碼停止encode(),假如是其他編碼格局的str,則須要先用該str的編碼停止decode(),轉成unicode後再應用寫入的編碼停止encode()。假如直接將unicode作為參數傳入write()辦法,Python將先應用源代碼文件聲明的字符編碼停止編碼然後寫入。
# coding: UTF-8
f = open('test.txt')
s = f.read()
f.close()
print type(s) # <type 'str'>
# 已知是GBK編碼,解碼成unicode
u = s.decode('GBK')
f = open('test.txt', 'w')
# 編碼成UTF-8編碼的str
s = u.encode('UTF-8')
f.write(s)
f.close()
別的,模塊codecs供給了一個open()辦法,可以指定一個編碼翻開文件,應用這個辦法翻開的文件讀取前往的將是unicode。寫入時,假如參數是unicode,則應用open()時指定的編碼停止編碼後寫入;假如是str,則先依據源代碼文件聲明的字符編碼,解碼成unicode後再停止前述操作。絕對內置的open()來講,這個辦法比擬不輕易在編碼上湧現成績。
# coding: GBK
import codecs
f = codecs.open('test.txt', encoding='UTF-8')
u = f.read()
f.close()
print type(u) # <type 'unicode'>
f = codecs.open('test.txt', 'a', encoding='UTF-8')
# 寫入unicode
f.write(u)
# 寫入str,主動停止解碼編碼操作
# GBK編碼的str
s = '漢'
print repr(s) # '\xba\xba'
# 這裡會先將GBK編碼的str解碼為unicode再編碼為UTF-8寫入
f.write(s)
f.close()
2.4. 與編碼相干的辦法
sys/locale模塊中供給了一些獲得以後情況下的默許編碼的辦法。
# coding:gbk
import sys
import locale
def p(f):
print '%s.%s(): %s' % (f.__module__, f.__name__, f())
# 前往以後體系所應用的默許字符編碼
p(sys.getdefaultencoding)
# 前往用於轉換Unicode文件名至體系文件名所應用的編碼
p(sys.getfilesystemencoding)
# 獲得默許的區域設置並前往元祖(說話, 編碼)
p(locale.getdefaultlocale)
# 前往用戶設定的文本數據編碼
# 文檔提到this function only returns a guess
p(locale.getpreferredencoding)
# \xba\xba是'漢'的GBK編碼
# mbcs是不推舉應用的編碼,這裡僅作測試注解為何不該該用
print r"'\xba\xba'.decode('mbcs'):", repr('\xba\xba'.decode('mbcs'))
#在筆者的Windows上的成果(區域設置為中文(簡體, 中國))
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
3.一些建議
3.1. 應用字符編碼聲明,而且統一工程中的一切源代碼文件應用雷同的字符編碼聲明。
這點是必定要做到的。
3.2. 擯棄str,全體應用unicode。
按引號前先按一下u最後做起來確切很不習氣並且常常會忘卻再跑歸去補,但假如這麼做可以削減90%的編碼成績。假如編碼困擾不嚴重,可以不參考此條。
3.3. 應用codecs.open()替換內置的open()。
假如編碼困擾不嚴重,可以不參考此條。
3.4. 相對須要防止應用的字符編碼:MBCS/DBCS和UTF-16。
這裡說的MBCS不是指GBK甚麼的都不克不及用,而是不要應用Python裡名為'MBCS'的編碼,除非法式完整不移植。
Python中編碼'MBCS'與'DBCS'是同義詞,指以後Windows情況中MBCS指代的編碼。Linux的Python完成中沒有這類編碼,所以一旦移植到Linux必定會湧現異常!別的,只需設定的Windows體系區域分歧,MBCS指代的編碼也是紛歧樣的。分離設定分歧的區域運轉2.4末節中的代碼的成果:
#中文(簡體, 中國)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
#英語(美國)
#sys.getdefaultencoding(): UTF-8
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
#德語(德國)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
#日語(日本)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp932')
#locale.getpreferredencoding(): cp932
#'\xba\xba'.decode('mbcs'): u'\uff7a\uff7a'
可見,更改區域後,應用mbcs解碼獲得了不准確的成果,所以,當我們須要應用'GBK'時,應當直接寫'GBK',不要寫成'MBCS'。
UTF-16同理,固然絕年夜多半操作體系中'UTF-16'是'UTF-16-LE'的同義詞,但直接寫'UTF-16-LE'只是多寫3個字符罷了,而萬一某個操作體系中'UTF-16'釀成了'UTF-16-BE'的同義詞,就會有毛病的成果。現實上,UTF-16用的相當少,但用到的時刻照樣須要留意。