1. 程式人生 > >Python2字串小結

Python2字串小結

1. 字元編碼問題

  • 字元的編碼
    計算機只能處理數字,這也就意味著當我們需要處理文字的時候,需要先把文字內容轉換成數字。這一轉換過程就是一個編碼的過程。編碼就相當於一個查字典的過程,我們要處理的文字就是我們不認識的字,然後需要通過查字典獲知它的讀音,這就是轉換後的數字。這一過程就叫做編碼,而我們所查的字典就叫做一個編碼集。一般來說,我們最早接觸的編碼方式就是ASCII編碼。這種方式是使用8個位元(bit)來編碼一個字元的,這種方式最對只能編碼256個字元。
  • 字元與字串
    字串是一組字元的集合,這倒是沒什麼可說的。不過,在C語言中,這個字元的定義還是和字串有那點不同的,這個是由於程式語言本身機制所致。C語言就使用ASCII編碼。

2. Unicode與UTF-8

  根據上面所說的字元編碼問題,就不難理解為什麼會有多種編碼方式的存在了。ASCII是好,但是它只能滿足美國人哪。那怎麼辦?別的國家的人只好再造些字符集出來了。反正就是字典嘛,你能造,我也能造,這樣一來,就有了各種字元編碼集了。就漢字編碼集來說,已經有好多種了。像GB2312、BIG5還有GBK等。這樣以來倒是可以各國人民都用上自家語言上網了。但是彼此間交流怎麼辦?
  就好像美國人有美國人韋氏詞典,英國人有牛津詞典,中國人有新華字典一樣。這麼多字典,彼此不同哪,這是一個問題。但是如果我們把所有這些字典內容都放到一本字典裡去,這不就成了全世界通用的字典了麼。前提是,這字典得足夠大。這和Unicode的思想是一致的。
  那麼,大家就都用Unicode編碼就是了,都能用嘛。但是問題就是Unicode要編碼所有的字元,那麼,這樣一來就不是一個字元能解決的問題了。但是這就引發問題了,大家可不太樂意用比一個位元組更多的儲存空間去儲存一個像’a’、’b’這樣的字元了。這不明擺著浪費空間哪。這個時候,就該UTF-8排上用場了。UTF-8的原則是能省則省,比如,能用一個位元組編碼的字元,那就用一個。這樣一來,就能省不少空間了。

3. 系統編碼、檔案編碼與Python編碼

  作業系統是要有編碼的,在 Linux 下獲取系統編碼結果如下:
  這裡寫圖片描述
  
  Linux 下預設使用UTF-8編碼。比如:
  這裡寫圖片描述 
  也就是說在 Linux 環境下預設檔案會使用 UTF-8 編碼。那麼,檔案編碼不言而喻了,就是該檔案使用哪種編碼方式。下面在 notepadqq 中使用不同的編碼方式編碼一個檔案,檢視其效果。
  這裡寫圖片描述 
  使用 encoviconv 做編碼轉換的時候始終有亂碼問題,就用了編輯器來做。可以看到,系統編碼總是確定的,檔案編碼總是對應所選擇的不同的編碼方式。
  這裡寫圖片描述
  
  這意味著 Python 直譯器會用 ASCII 編碼的方式去解讀 Python 原始檔。這樣導致的直接問題就是,當在 Python 原始檔中存在非 ASCII 字元時,會導致 Python 直譯器無法識別,繼而導致編碼錯誤。

# coding.py
print '編碼問題'

執行結果如下:

這裡寫圖片描述

所以,這個時候需要告訴 Python 直譯器用 UTF-8 去讀 Python 原始檔。

# -*- coding: utf8 -*-
# coding.py
print '編碼問題'

這裡寫圖片描述

4. Python2 字串編碼

  Python2 中以 Unicode 為中間碼,即所有的編解碼都是以 Unicode 為媒介進行的。

 1 #coding=utf-8
 2 
 3 s='漢字'
 4
 5 if isinstance(s, unicode):
 6 # 判斷 s 是否是 unicode 字元
 7    gs = s.encode('gb2312')
 8 else:
 9    gs = s.decode('utf8').encode('gb2312')

  這個其實就是通過 unicode 進行的。下面再看一個例子:
  這裡寫圖片描述
  
  可以看到,’hello’ 字串包含的都是 ascii 可編碼字元,由於 python2 預設使用 ascii 編碼,可以通過。而 ‘漢字’ 則是不可用 ascii 編碼的字元,所以,這個時候 python 再去用 ascii 對其 decode 的時候,就出錯了。其實,上面的這個 encode 方法的機制應該是先通過指定的編碼方式(python2 預設 ascii)對目標字串進行 decode 成 unicode 碼,然後該 unicode 碼作為中間程式碼接著 encode 成指定的編碼方式。所以,在 ‘漢字’.encode(‘gbk’) 的過程中,python 首先使用 ascii 對 ‘漢字’ 進行 decode,當然這個時候是錯誤的。
  這裡寫圖片描述
 
  所以,python 字串編解碼的全部問題都在於這個中間碼 —— Unicode碼。

5. 字串、Unicode字串及原始字串

python2 中有兩類字串,分別是 str 與 unicode。這兩類字串都派生自一個抽象類 basestring。
這裡寫圖片描述

那麼,對於一個 python 字串來說,就有兩種選擇了。

這裡寫圖片描述

至於原始字串(或者說是原生)則是一種轉義了反斜線(‘\’)的字串。

這裡寫圖片描述

可以看到,在原始字串中,反斜線已經被轉義了。

6. 字串兩個方法

  • 字串轉列表:
s = 'str,list,tuple,dict,set'
rs = s.split(',')
  • 列表轉字串:
s = '&'.join(['java', 'python', 'js'])