19.python的編碼問題

来源:http://www.cnblogs.com/scolia/archive/2016/06/03/5554768.html
-Advertisement-
Play Games

在正式說明之前,先給大家一個參考資料:戳這裡 文章的內容參考了這篇資料,並加以總結,為了避免我總結的不夠完善,或者說出現什麼錯誤的地方,有疑問的地方大家可以看看上面那篇文章。 以下說明是針對於python2.x版本,因為在python3.x中預設使用的是Unicode。 下麵開始講python中的編 ...


  在正式說明之前,先給大家一個參考資料:戳這裡

  文章的內容參考了這篇資料,並加以總結,為了避免我總結的不夠完善,或者說出現什麼錯誤的地方,有疑問的地方大家可以看看上面那篇文章。

  以下說明是針對於python2.x版本,因為在python3.x中預設使用的是Unicode。

  下麵開始講python中的編碼問題,首先,我們看看編碼有哪些。

  1. ASCII

  ASCII是用一個位元組表示字元,而一個位元組由八位二進位組成,所以能產生2**8=256種變化,在電腦剛誕生的年代,用來表示大小寫的26個英文字母,外加一些符號之類的還是綽綽有餘的。這也是python2.x中預設使用的編碼,所以在python2.x中預設不能使用中文,除非使用編碼聲明。

  2. MBCS

  隨著時代的發展,ASCII就太夠用了,電腦不能只顯示英文吧,那樣實在太low。此時,大家看到ASCII碼中還有沒用完的,所以都想占用剩下的部分,但是剩下的部分還是不夠,例如我們中文那麼多肯定是不夠用的,所以此時又擴展了一下,一個位元組不行,我就用兩個。而又為了相容ASCII碼,有定義了這樣一套規則:如果第一個位元組是\x80以下,則仍然表示ASCII字元;而如果是\x80以上,則跟下一個位元組一起(共兩個位元組)表示一個字元,然後跳過下一個位元組,繼續往下判斷。例如GB...和BIG...之類的都遵循這樣的規則。

  但是,這樣還是實在太亂了,此時IBM跳了出來,大喊一聲:這些東西都要統一進行管理!!所以弄出了代碼頁的概念,將這些字元集都收錄了起來,併進行了分頁,而這些分頁的總稱就叫MBCS,例如GBK在936頁,所以又叫cp936。而大家都是使用的雙位元組,所以也稱為DBCS。

  但很明顯,MBCS裡面收集和各樣的字元集,但是你不能說你要使用MBCS這個字元集編碼,裡面存了怎麼多種,到底是要用哪種,你不說清楚我總不能隨機給你一種吧。所以必須要進行指定,但是這個工作已經由操作系統自己完成了(linux不支持),而操作系統有時根據地區的不同而選擇的。例如簡體中文版的,就選GBK,其他國家的又會有不同,具體按版本而定。所以,一旦在python的編碼聲明中使用MBCS/BDCS,在進行過系統或跨地區運行的時候,報錯也是在所難免的。所以編碼聲明中一定要具體的指定,例如我們常用的utf-8,這樣就不會因為系統和地區的差異而造成各種編碼的錯誤。

  在windows中,微軟又為它起了個別名,叫ANSI,其實就是MBSC,大家知道就好了。

  3.Unicode

  雖然MBSC一定程度上解決了編碼混亂的問題,但還是特點的編碼只能顯示特點的字元。這樣要開發一種適配多國語言的程式就變得非常困難,此時人們在想,有沒有一種編碼能搞到所以的字元。大家研究了一番之後,Unicode就此誕生。乾脆大家都不要在ASCII上拓展來拓展去,搞得各種版本如此混亂。以後大家都用兩個位元組保存算了,這樣就有了256*256=65536種字元可以表示了,總歸是夠用了吧。這就是UCS-2標準了。後來還有人說不夠用的,那麼乾脆翻一倍,用四個位元組表示,256**4=4294967296,就算將來表示外星文字也能撐一段時間了吧。當然現在常用的還是UCS-2標準的。

  UCS(Unicode Character Set)還僅僅是字元對應碼位的一張表而已(也就是表示位元組),比如"漢"這個字的碼位是6C49。字元具體如何傳輸和儲存則是由UTF(UCS Transformation Format)來負責(也就是保存位元組)。(註意:表示位元組≠保存位元組,也就是雖然我用了2個位元組表示字元,但是我保存的時候不一定就直接保存用來表示的那個位元組)

  剛開始都是直接使用UCS的碼位來保存,這就是UTF-16,比如,"漢"直接使用\x6C\x49保存(UTF-16-BE),或是倒過來使用\x49\x6C保存(UTF-16-LE)。但美國佬後來不願意了,我原來用ASCII只有1個位元組就能搞到,現在卻要兩個位元組,足足長了一倍呀。一倍是什麼概念,四捨五入那是將近一個億呀真當我磁碟空間不用錢呀,為了滿足這個述求,就誕生了UTF-8。

  UTF-8是一種很彆扭的編碼,具體表現在他是變長的,並且相容ASCII,ASCII字元使用1位元組表示。但有得必有失,在UTF-8中,東亞的文字是用三個位元組表示的,包括中文,一些不常用的字元更是用四個位元組表示。於是別的國家保存的成本變高了,而美國佬卻變低了。又再次坑了別人,滿足了自己。但是沒辦法,誰叫人家是電腦界的老大呢?

 

什麼是BOM

   當一個文本編輯要打開一個文件時,它表示懵逼了。世間編碼如此之多,我究竟要用什麼哪種編碼去解碼呀?你總得告訴我吧!

  此時,UTF就進入了BOM來表示編碼。所謂的BOM就是文件使用編碼的標識符,就和python的編碼聲明一樣,告訴文本編輯器我用的是什麼編碼,下麵的你都用那個編碼去解碼就行。

  同樣的,只有文本編輯器在文件開頭的地方讀到了關於BOM的描述,就能夠進行正確的界面了。

  下麵是一些BOM的總結:

  BOM_UTF8 '\xef\xbb\xbf'
  BOM_UTF16_LE '\xff\xfe'
  BOM_UTF16_BE '\xfe\xff'

  同樣了,為了我們自己編輯的文件的編碼也能被正確識別,我們也要寫入BOM,一般由編輯器完成。但不寫也可以,只有在打開文件的時候自己手動選擇用什麼去解碼也是可以的。

  但是,還有一種叫UTF-8無BOM模式的,這又是什麼鬼。

  因為UTF-8實在太流行了,所以文本編輯器預設會首先用UTF-8進行解碼。即使是保存時預設使用ANSI(MBCS)的記事本,在讀取文件時也是先使用UTF-8測試編碼,如果可以成功解碼,則使用UTF-8解碼。記事本這個彆扭的做法造成了一個BUG:如果你新建文本文件並輸入"奼塧"然後使用ANSI(MBCS)保存,再打開就會變成"漢a"。)

  下用一幅圖來總結:

  此時,有些人會在MBCS和UCS-2之間迷糊,大家都是兩個位元組表示,又有什麼不同?

  MBCS是各自拓展的,有就是說很可能相同的二進位表示MBCS會出現不同的結果,而Unicode是統一拓展,保證了每種二進位表示都對應唯一一個字元,保證了唯一性,也就提高了相容能力。

 


   

  ok,在講完字元編碼的問題之後,現在再來看一下:

   # coding:gbk 和 # coding= utf-8 之類的編碼聲明對python而言到底意味著什麼。

  這裡插播一個小技巧:

   # coding : utf-8 或者這樣 # coding = utf-8 的聲明方式是會報錯的,這裡並不是說是特點的=或者:的問題,而是空格的問題,在coding和符號之間是不能有空格的,但在符號和utf-8之類的編碼名稱間是運行0個或多個空格的,#和coding間也是運行0個或多個空格的。我也不知道為什麼,但實際就是報錯了。

#! /usr/bin/env python
#coding = utf-8
print '中文'

 

  這裡coding和=號一個空格:

  報錯了。

#! /usr/bin/env python
#coding= utf-8
print '中文'

  coding和=之間沒空格:

  正常執行。

  不清楚是我IDE的問題還是python本來的語法是這樣規定的,但其實很少有地方談及這個地方的語法,所以這裡提及一下,最後自己實驗一下。

   # -*- coding: utf-8 -*- 的寫法也是一樣的。

 

  好了,一下進入正題:

#! /usr/bin/env python
# coding= utf-8
print '中文'
print str('中文')
print repr('中文')
print repr(u'中文')

 

  這裡順便解釋一下str()函數和repr()函數在創建或轉換字元串上的區別,str()得到是一個對人類可讀性比較好的字元串,而print也是預設調用這個函數的。而repr()是創建或轉換字元串時,得到是對機器可讀性更好的字元串,就是這裡得到是其編碼。

  下麵是另一種編碼的輸出:

#! /usr/bin/env python
# coding= gbk
print '中文'
print str('中文')
print repr('中文')
print repr(u'中文')

 

 

  前面兩個是亂碼,不過這裡是我IDE的問題,我的IDE預設是用UTF-8的。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • C++這門語言從誕生到今天已經經歷了將近30個年頭。不可否認,它的學習難度都比其它語言較高。而它的學習難度,主要來自於它的複雜性。現在C++的使用範圍比以前已經少了很多,java、C#、python等語言在很多方面已經可以代替C++。但是也有很多地方是其他語言完全無法替代的,主要集中在需要運行效率比 ...
  • Ok,我又來寫SOLR的內容了,昨天做了修改和增加的增量索引,今天來說說關於刪除的增量索引以及定時更新增量索引,廢話不多說,下麵進入正文。 一、增量索引之刪除 昨天已經說過,增量索引其實就是SOLR對上次做過(增量或者全量)索引之後到這次做索引之間的這段時間資料庫發生變化的數據進行創建索引,昨天我們 ...
  • 1. D:\AWS_workspace\DAAS_Go>go get -u -ldflags -H=windowsgui github.com/nsf/gocode 2. Then gocode.exe will be installed in "D:\AWS_workspace\DAAS_Go\b ...
  • http://blog.csdn.net/hengyunabc/article/details/7371446 本文章地址:http://blog.csdn.net/hengyunabc/article/details/7371446 2012-03-31:新版的goclipse改進很大,本文有些內 ...
  • 最近想學習下Go語言,先從最基本的Hello Go開始,搭建Go開發環境 一、下載Go包 由於Go官網國內訪問經常有問題,可以從國內的鏡像下載: http://www.golangtc.com/ 二、配置環境變數 1、將Go的壓縮包解壓到任意目錄,我的為D:\SDE\go 2、 配置GoRoot路徑 ...
  • http://www.cnblogs.com/qgymje/p/3912259.html 這篇原來是給公司里使用go開發的交流用的,主要是工具的安裝,用markdown寫的,發佈了內部gitlab上,倉促發佈到blog上面,也沒改啥格式,現在整理一下,然後增加一點說明 基礎開發工具 sublime ...
  • http://www.distilnetworks.com/setup-go-golang-ide-for-mac-os-x/#.V1Byrf50yM8 Programming in Go (Golang) – Setting up a Mac OS X Development Environmen ...
  • Spring Mvc簡介: Spring Web MVC是一種基於Java的實現了Web MVC設計模式的請求驅動類型的輕量級Web框架,即使用了MVC架構模式的思想,將web層進行職責解耦,基於請求驅動指的就是使用請求-響應模型,框架的目的就是幫助我們簡化開發,Spring Web MVC也是要簡 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...