Python亂碼九問

更多精彩內(nèi)容薪捍,請關(guān)注微信公眾號:后端技術(shù)小屋

大家可能和我一樣,在Python日常開發(fā)過程中會遇到各種各樣的編碼問題配喳。因此在此以個(gè)人的踩坑經(jīng)驗(yàn)總結(jié)出一些常見問題和解決方案酪穿。

0 如何查看py源文件編碼

vim py文件
輸入

:set fileencoding

輸出

fileencoding=utf-8

1 如何確定py中靜態(tài)字符串的編碼

靜態(tài)字符串的編碼方式取決于文件頭中coding的設(shè)置。在下面的代碼中晴裹,變量name以UTF-8編碼被济。

#!/usr/bin/env python
# coding: utf-8
name = "后端技術(shù)小屋"

如果不設(shè)置coding,運(yùn)行py文件時(shí)便會報(bào)語法錯(cuò)誤涧团,因?yàn)镻ython Interpreter不識別文件中的中文字符

SyntaxError: Non-ASCII character '\xe5' in file 1.py on line 2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

2 如何查看標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出的編碼

以下三種方法皆可查看stdin/stdout的編碼

2.1 通過Python sys庫查看

$ python 
Python 2.7.6 (default, Nov 13 2018, 12:45:42) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print sys.stdin.encoding
UTF-8
>>> print sys.stdout.encoding
UTF-8
>>> 

2.2 查看環(huán)境變量LANG

$ echo $LANG
en_US.UTF-8

2.3 執(zhí)行l(wèi)ocale

$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US:
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

3 如何修改標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出的編碼

首先我們需要知道是環(huán)境變量LANG決定了stdinstdout的編碼

如果只是想臨時(shí)修改只磷,在命令行通過export LANG='XXX'指定標(biāo)準(zhǔn)輸入/輸出編碼即可。當(dāng)終端退出時(shí)該設(shè)置即失效少欺。

如果想永久修改: 執(zhí)行vim /etc/sysconfig/i18n, 在其中修改LANG的取值喳瓣,然后執(zhí)行source /etc/sysconfig/i18n即可生效。

4 定義字符串時(shí)前綴'u'和'b'的區(qū)別

首先我們假設(shè)py文件頭中# coding: utf-8

執(zhí)行a = u'后端技術(shù)小屋'時(shí)赞别,會將UTF-8編碼的靜態(tài)字符串轉(zhuǎn)化成Unicode編碼畏陕,最后賦值給a;

執(zhí)行b = b'后端技術(shù)小屋'時(shí)仿滔,則直接將UTF-8編碼的靜態(tài)字符串賦值給b

5 定義a=u'后端技術(shù)小屋'和b=b'后端技術(shù)小屋'惠毁,打印a和b的結(jié)果為何相同

假設(shè)py文件頭中指定coding為UTF-8,且標(biāo)準(zhǔn)輸入/輸出的編碼為UTF-8

Python執(zhí)行print a時(shí)崎页,會自動將Unicode轉(zhuǎn)化成標(biāo)準(zhǔn)輸出的編碼格式UTF-8鞠绰,然后輸出

Python執(zhí)行print b時(shí),字符串b的編碼為UTF-8飒焦,恰好與標(biāo)準(zhǔn)輸出相同蜈膨。雖然定義a和b時(shí)的編碼方式不同,但是打印它們時(shí)都會轉(zhuǎn)化為標(biāo)準(zhǔn)輸出的編碼牺荠,所以我們看到打印a和b的結(jié)果相同翁巍。

實(shí)際上這里有一些巧合:字符串b的編碼恰好與標(biāo)準(zhǔn)輸出相同。一旦b的編碼和標(biāo)準(zhǔn)輸出的編碼不一致了(比如b的編碼換成了GBK)休雌,我們看到的將是亂碼灶壶,因?yàn)镚BK編碼無法自動轉(zhuǎn)化為UTF-8,而我們在Python開發(fā)中遇到的中文亂碼問題大部分來源于此杈曲。

在實(shí)際開發(fā)中驰凛,強(qiáng)烈建議將可能含有中文的字符串一律轉(zhuǎn)換成Unicode編碼之后再打印胸懈。如下所示:

# coding: gbk
a = "后端開發(fā)小屋"     # GBK編碼
aa = a.decode("gbk")  # Unicode編碼
print aa                
# coding: utf-8
a = "后端開發(fā)小屋"        # UTF-8編碼
aa = a.decode("utf-8")   # Unicode編碼
print aa

6 執(zhí)行py的標(biāo)準(zhǔn)輸出重定向到文件中是什么編碼?

編碼方式同標(biāo)準(zhǔn)輸出

7 為何vim打開文件無亂碼恰响,但是cat文件有亂碼

說明文件和標(biāo)準(zhǔn)輸出編碼不一致趣钱。而vim支持文件編碼,所以vim打開文件無亂碼渔隶,cat文件有亂碼羔挡。所以解決思路是使得文件編碼與標(biāo)準(zhǔn)輸出編碼一致,即可消除亂碼间唉。

解決方法1: 通過iconv -f XXX -t XXX file, 將文件轉(zhuǎn)碼绞灼,使得其編碼與標(biāo)準(zhǔn)輸出一致

解決方法2: 修改標(biāo)準(zhǔn)輸出編碼(參考問題2), 使得其與文件編碼一致

8 vim打開文件有亂碼,但是cat文件無亂碼

說明vim不識別此種文件編碼

解決方法:

  • vim中輸入:set fileencoding, 查看文件編碼
  • vim ~/.vimrc, 在set fileencodings列表中加入該文件編碼呈野,例如set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,euc-kr,latin1
  • vim重新打開文件

9 總結(jié)

說了這么多低矮,總結(jié)下:

  • Python開發(fā)中,對于可能含有中文的字符串被冒,如需打印军掂,需將其轉(zhuǎn)化為Unicode編碼。因?yàn)閜ython會自動將unicode轉(zhuǎn)化成輸出介質(zhì)的編碼昨悼。
  • 標(biāo)準(zhǔn)輸出蝗锥、標(biāo)準(zhǔn)輸入、文件率触、vim(或其他編輯器)上的亂碼問題终议,可根據(jù)如上問題舉一反三,對癥下藥加以解決葱蝗。

推薦閱讀

更多精彩內(nèi)容穴张,請掃碼關(guān)注微信公眾號:后端技術(shù)小屋。如果覺得文章對你有幫助的話两曼,請多多分享皂甘、轉(zhuǎn)發(fā)、在看悼凑。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末偿枕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子户辫,更是在濱河造成了極大的恐慌益老,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寸莫,死亡現(xiàn)場離奇詭異,居然都是意外死亡档冬,警方通過查閱死者的電腦和手機(jī)膘茎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門桃纯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人披坏,你說我怎么就攤上這事态坦。” “怎么了棒拂?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵伞梯,是天一觀的道長。 經(jīng)常有香客問我帚屉,道長谜诫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任攻旦,我火速辦了婚禮喻旷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘牢屋。我一直安慰自己且预,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布烙无。 她就那樣靜靜地躺著锋谐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪截酷。 梳的紋絲不亂的頭發(fā)上涮拗,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機(jī)與錄音合搅,去河邊找鬼多搀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛灾部,可吹牛的內(nèi)容都是我干的康铭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赌髓,長吁一口氣:“原來是場噩夢啊……” “哼从藤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锁蠕,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤夷野,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后荣倾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悯搔,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年舌仍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妒貌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片通危。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖灌曙,靈堂內(nèi)的尸體忽然破棺而出菊碟,到底是詐尸還是另有隱情,我是刑警寧澤在刺,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布逆害,位于F島的核電站,受9級特大地震影響蚣驼,放射性物質(zhì)發(fā)生泄漏魄幕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一隙姿、第九天 我趴在偏房一處隱蔽的房頂上張望梅垄。 院中可真熱鬧,春花似錦输玷、人聲如沸队丝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽机久。三九已至,卻和暖如春赔嚎,著一層夾襖步出監(jiān)牢的瞬間膘盖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工尤误, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侠畔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓损晤,卻偏偏與公主長得像软棺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子尤勋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容