1. 程式人生 > >五分鐘戰勝 Python 字元編碼

五分鐘戰勝 Python 字元編碼

對於很多接觸Python的人而言,字元的處理和語言整體的溫順可靠相比顯得格外桀驁不馴難以駕馭。

本文不談複雜的理論,就經驗教你字元處理八字真言:確定編碼,同類互動。

文章針對Python 2.7,主要因為3對的編碼已經有了很大的改善並且實際原理一樣,更改一下操作命令即可。

瞭解完本文,你可以輕鬆解決文書處理,特殊平臺(Windows?)下的編碼,爬蟲編碼等問題。

閱讀建議

本文分為如下幾個部分:

  • 原理
  • 具體操作
  • 建議的使用習慣
  • 疑難問題解答

如果想要了解我給出的使用習慣,可以直接跳到建議的使用習慣。

如果只想要解決相關問題可以直接跳到疑難問題解答。

希望本文能夠幫到你。

原理

為了理解方便,這裡不談理論只做類比,具體想要進一步瞭解各種編碼的理論的搜狗一下好了。

首先說一下我們為什麼會碰到各式各樣的編碼問題:

  • 因為我們沒有統一編碼
  • 因為我們沒有用對命令(傳對資料)

再說一下編碼是什麼,Python的編碼看似複雜,實際上可以看做只有兩類編碼:Unicode,二進位制

  • Unicode 相信都很熟悉:,就是\u0000這樣的
  • 二進位制編碼也很簡單,就是\x00\x00這樣的,平常看到的utf-8,cp936都是二進位制編碼
  • 二進位制編碼是具象的,10001100原樣就可以儲存,而Unicode是抽象的,不能這樣存
Python
1234567891011 #coding=utf8# Unicode編碼演示print('Unicode:')print(repr('Unicode編碼'))`# 二進位制編碼演示print(u'二進位制編碼:')print(repr('Unicode編碼'))`# 只是看個樣子,程式碼不必去深究

再說怎麼做,就是隻有同種編碼之間才可以操作

  • 舉個簡單的類比
    Python
    1234 就把一串資料比為烤鴨,我們作為人和鴨子不同種看待烤鴨的態度完全不一樣。我們看到的是晚上的配菜,鴨子看到的是自己二舅。那麼我在逛烤鴨店的時候用錯編碼就會報錯。因為我在烤鴨店看到了滿世界的二舅。
  • 這裡說的同種就是我們熟悉的各種編碼方式:utf-8,unicode,ucs-bom
  • 這也就是編碼問題的核心,非常重要。

最後說一下Python的環境

  • 本身程式碼是用Ascii解碼的,檔案裡有Ascii無法解碼的內容的話要告知Python怎麼解碼
  • 內部大量命令都是預設接受Unicode
Python
123 # 告知的命令就是下面這一行,刪掉就會報錯#coding=utf8print(u'測試編碼')

具體操作

拿到各種編碼的內容自然是不用說,那麼如果我們想要自己構造怎麼做呢,看下面:

Python
123456789 #coding=utf8# 字串前面加u會預設構造出Unicode的字串unicodeString=u'Unicode字串'# 字串前面什麼都不加會構造出預設編碼(首行限定了現在的utf8)的字串utf8String='Utf-8字串'# 當然,沒有首行,預設的編碼是Ascii

那麼他們之間怎麼轉換呢,同樣很簡單:

Python
12345678910 # 接上一段程式# Unicode轉化為二進位制編碼中的一種:utf8unicodeString.encode('utf8')# 二進位制編碼根據自己的編碼種類轉化為Unicodeutf8String.decode('utf8')# 如果二進位制編碼中混進了奇怪的東西可以根據需求用特殊的decode策略print(repr('u8字\x00符串'.decode('utf8','replace')))

那麼怎麼樣會出現問題呢:

Python
1234567891011 # 接上一段程式# 如果我們把他們轉化成同樣的編碼方式就可以操作(例如相加)print(repr(unicodeString+utf8String.decode('utf8')))print(repr(unicodeString.encode('utf8')+utf8String))# 但如果不轉化,當然就會出現滿世界的烤鴨二舅啦unicodeString+utf8String# 所以另一方面也發現,編碼轉換是需要我們告訴程式怎麼做的# 所有`decode`操作都會生成Unicode編碼,這是為了方便我之前說的大量接受Unicode的內部命令

所以我們需要確定程式使用的編碼,這是我們需要告訴程式的東西

  • 一方面在操作字串的時候確定是同種編碼
  • 另一方面在使用非自己寫的命令時,一般使用Unicode,或者使用接收二進位制編碼的命令
Python
1234567891011 #coding=utf8# 這裡拿寫入檔案舉例# 一般使用Unicodewithopen('Unicode.txt','w')asf:f.write(u'Unicode測試')# 或者使用接收二進位制編碼的命令withopen('Utf8.txt','wb')asf:f.write('Utf8測試')# 你可以反過來做個測試,自然會報錯# 二進位制的命令方便了在不知道怎麼解碼的情況下也能進行操作(寫入檔案)

我建議的使用習慣

相信到這裡我已經把我對於編碼的理解講完了。

我們為什麼會碰到各式各樣的編碼問題:

  • 因為我們沒有統一編碼
  • 因為我們沒有用對命令(傳對資料)

所以這裡再重申一下八字真言:確定編碼,同類互動

  • 碰到問題,問一下自己,我現在是哪種編碼
  • 同一種編碼才能互動,那我應該是哪種編碼

這裡給出我的使用習慣:

  • 確定一種內部編碼
  • 內部編碼的選擇優先順序如下:程式必須使用的編碼、第三方包使用的編碼、你喜歡的編碼、Unicode
  • 在輸出時再更改到特定的編碼

記得在開始整個程式之前確定內部的編碼,否則編碼一團糟會產生很多不必要的bug。

不要迷信內部Unicode,例如Evernote開發就應該根據第三方包使用的Utf8確定內部編碼。

疑難問題解答

編碼識別

說了要確定編碼,那麼拿到一串二進位制要怎麼確定編碼呢?

最簡單的方法是chardet:(需要安裝)

Python
1 python-mpip install chardet

使用非常簡單:

Python
123456 #coding=utf8fromchardet importdetectprint(detect('這是一串utf8的測試字元'))# 結果:`{'confidence': 0.99, 'encoding': 'utf-8'}`

另外例如抓取網站,那麼標頭檔案中很有可能有提示如何解碼,記得不要忘記了。

編碼轉換

很可能因為字串中參雜了奇怪的東西,導致即使編碼種類正確,依舊無法解碼。

我知道我之前講過了,但可能有人直接跳疑難問題解答嘛。

這裡可以使用decode的第二個引數:

Python
12345678 #coding=utf8# 字串中混進了\x00rubbishUtf8String='Utf-8字\x00符串'print(repr(rubbishUtf8String.decode('utf8','replace')))print(repr(rubbishUtf8String.decode('utf8','ignore')))

特殊平臺下編碼

很多人都說Windows是個坑,即使在Python 3下面也一樣。

因為中文檔名出來都是亂碼。

這裡使用一個取巧的方法:平臺編碼再特殊,起碼命令列讀取和建立一個資料夾不會出亂碼吧。

Python
1234 importsys,osforfolder inos.walk('.').next()[1]:print(folder.decode(sys.stdin.encoding))

同樣的輸入輸出也可以這樣做優化:

Python
1234567 importsysdefsys_print(msg):print(msg.encode(sys.stdin.encoding))defsys_input(msg):returnraw_input(msg.encode(sys.stdin.encoding)).decode(sys.stdin.encoding)

檔案寫入

如果抓下來一個內容不知道怎麼解碼,但還是想要寫入檔案怎麼辦

寫入檔案的時候制定用二進位制命令即可:

Python
123456789 #coding=utf8importurllibwithopen('Utf8.txt','wb')asf:f.write('Utf8測試')# 比如抓了個網頁,不知道編碼也可以寫入檔案進行一系列操作content=urllib.urlopen('http://www.baidu.com').read()withopen('baidu.txt','wb')asf:f.write(content)

裸Unicode字元

Unicode存成六個Ascii字元怎麼辦?其實也可以decode

Python
123456789101112131415 #coding=utf8# 這是普通的Unicodes=u'測'foriins:print(i)print(repr(s))# 這是裸Unicode,實際存成了六個Asciis=repr(s)[2:-1]foriins:print(i)print(repr(s))# 轉化其實也很簡單s=s.decode('unicode-escape')foriins:print(i)print(repr(s))

結束語

希望讀完這篇文章能對你有幫助,有什麼不足之處萬望指正(鞠躬)。

有什麼想法或者想要關注我的更新,歡迎來GithubStar或者Fork我的專案。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

相關推薦

分鐘戰勝 Python 字元編碼

對於很多接觸Python的人而言,字元的處理和語言整體的溫順可靠相比顯得格外桀驁不馴難以駕馭。 本文不談複雜的理論,就經驗教你字元處理八字真言:確定編碼,同類互動。 文章針對Python 2.7,主要因為3對的編碼已經有了很大的改善並且實際原理一樣,更改一下操作命令即可。 瞭解

python字元編碼和檔案處理

  一.瞭解字元編碼的知識儲備 1.文字編輯器存取檔案的原理(nodepad++,python,word)   開啟編輯器就打開了啟動了一個程序,是在記憶體中的,所以,用編輯器編寫的內容也都是存放於記憶體中的,斷電後資料丟失 要想永遠儲存,需要點選儲存按鈕:編輯器

深入理解python字元編碼(包含2.x與3.x)

2018-11-29  09:44:30 引子    計算機要想工作必須通電,即用‘電’驅使計算機幹活,也就是說‘電’的特性決定了計算機的特性。 電的特性即高低電平(人類從邏輯上將二進位制數1對應高電平,二進位制數0對應低電平), 關於磁碟的磁特性也是同樣的道理。

談談python字元編碼問題

ascii編碼 ASCII可以編碼英文字元,0-9數字,以及一些可列印字元,不可列印字元等。 在那個時候,編寫程式只使用這個編碼就足夠,一個字元通過寫入後,在記憶體中儲存為其對應的ASCII編號,當從記憶體中讀出時,把對應的ASCII編號轉換成對應的字元即可。 UNICODE編

徹底搞清楚python字元編碼

在討論python編碼之前,我先了解了幾種編碼的由來。 一、編碼型別 1、ascci碼 ascci碼由美國人發明,用1個位元組(byte)儲存英文和字元,前期用了128個,後來新加了其他歐洲國家的符號,128~255這一段。 256個字元,基本上就是鍵盤上的

Python 字元編碼

準備 python3中,所有的字串在記憶體中均是unicode儲存(記憶體中都是如此,包括我們在開啟txt檔案的時候),當需要儲存到硬碟或者需要傳輸的時候,轉換為其他編碼(GBK,UTF-8) str型別在記憶體中是以unicode形式存在的 bytes型

我說帶你分鐘學會Python協程就分鐘!不會超過六分鐘

協程由於由程式主動控制切換,沒有執行緒切換的開銷,所以執行效率極高。對於IO密集型任務非常適用,如果是cpu密集型,推薦多程序+協程的方式。 在Python3.4之前,官方沒有對協程的支援,存在一些三方庫的實現,比如gevent和Tornado。3.4之後就內建了asyncio標準庫,官方

【筆記】Python字元編碼

一、字元編碼(文字的編碼指的是字元如何使用位元組來表示組織方式) 1、ASCII 英文字母大小寫,特殊字元,數字,早期ASCII 字元編碼規定使用單位元組中低位的7個位元去編碼所有的字元(\x80以下),ASCII 擴充字符集利用了後128個字元。 2、Unic

python 字元編碼與解碼——unicode、str和中文:UnicodeDecodeError: 'ascii' codec can't decode

摘要:在進行python指令碼的編寫時,如果我們用python來處理網頁資料或者進行與中文字元有關的處理工作,經常出現這樣的出錯資訊:SyntaxError: Non-ASCII character '\xe6' in file ./filename.py on line

Python 字元編碼學習-ascii編碼,Unicode和UTF-8之間的關係

ascii編碼,Unicode和UTF-8之間的關係 1,ascii編碼,這是一種單位元組編碼,8位,一個char的長度。最多可以存放255中不同的字元。對於早期的計算機系統來說,對於應付英文字元和一些符號綽綽有餘了。 事實上基本的ascii碼只用了128個。

Python字元編碼與正則表示式指南

1. 字元編碼簡介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一種單位元組的編碼。計算機世界裡一開始只有英文,而單位元組可以表示256個不同的字元,可以表示所有的英文字元和許多

python 字元編碼處理總結

問題引入python中經常遇到這樣那樣的字元編碼問題,尤其在處理網頁原始碼時(特別是爬蟲中):U

python:字元編碼與轉碼

字元編碼與轉碼 詳細文章: http://www.cnblogs.com/yuanchenqi/articles/5956943.html http://www.diveintopython3.net/strings.html 需知: 1.在python2預設編碼

Python字元編碼和二進位制不得不說的故事

二進位制 核心思想:   馮諾依曼 + 圖靈機   電如何表示狀態,才能穩定?     計算機開始設計的時候並不是考慮簡單,而是考慮能自動完成任務與結果的可靠性,     簡單始終是建立再穩定、可靠基礎上     經過嘗試10進位制,但很

[學習筆記] 分鐘快速理解字符集與字元編碼的區別

字符集 字符集,也稱作字元編碼方案,是為字元集合中每一個字元分配一個唯一ID的編碼字符集.包括了Unicode,ASCII,ANSI等字符集。 Unicode字符集 — 所有字元組成的字符集 國際組織制定的可以容納世界上所有文字和符號的字元編碼方案。如果全世界每一個符號都給予一個

第二篇 Python資料型別、字元編碼、檔案處理

一、引子     1、什麼是資料?         x=10,10是我們要儲存的資料     2、為何資料要分不同的型別    

教表弟學了半個月的Python!他居然才學會字典!分鐘學會的東西

今天不是禮拜五嘛。我姑媽帶著我表弟來到我家玩!然後和我媽嘮嗑嘛!然後就扯到我的工作上面來了!我就是一個小萌新,大佬帶著能拿個10k左右,所以我姑媽就問起了我這個行業,我說了大大小小一堆,然後他們估計也聽不懂!我表弟呢,是個高中畢業就沒上學了的小老弟。給他姑媽守守小賣部的, 所以文化水平嘛。不算高不算

python基礎--字元編碼

一 、什麼是編碼? 基本概念很簡單。首先,我們從一段資訊即訊息說起,訊息以人類可以理解、易懂的表示存在。我打算將這種表示稱為“明文”(plain text)。對於說英語的人,紙張上列印的或螢幕上顯示的英文單詞都算作明文。 其次,我們需要能將明文表示的訊息轉成另外某種表示,我們還需要能將編碼文

python開發基礎之資料型別、字元編碼、檔案操作

一、知識點 1.身份運算: 2.現在計算機系統通用的字元編碼工作方式:在計算機記憶體中,統一使用Unicode編碼,當需要儲存到硬碟或者需要傳輸的時候,就轉換為UTF-8編碼。用記事本編輯的時候,從檔案讀取的UTF-8字元被轉換為Unicode字元到記憶體裡,編輯完成後,儲存的時候再把Unicode轉

python基礎 字元編碼

一.計算機基礎知識   應用程式任何操作硬體的的請求,都需要向作業系統發起呼叫,然後由作業系統去呼叫;   cpu----記憶體-----硬碟   二.文字編輯器存取檔案的原理   1.開啟編輯器就打開了一個啟動的進行,是在記憶體中,所以編輯器編寫的內容也都是存放於記憶體中的,斷電後資料丟