Python 的字符編碼


配置: Python 2.7 + Sublime Text 2 + OS X 10.10

本文意在理清各種編碼的關系並以此解決 Python 中的編碼問題。

1 編碼基本概念

只有先了解字符表、編碼字符集、字符編碼三者的基本概念,才能直入編碼問題的核心。

1.1 字符表 | Abstract Character Repertoire

字符表是一個系統支持的所有可讀或者可顯示的抽象字符的集合。也就是說字符表里面的元素是可顯示的字符。例如:“A”、“B”、“文”這樣的元素。

1.2 編碼字符集 | Coded Character set

編碼字符集是這樣的一個集合,集合中的元素是字符在字符表中的位置。例如元素 65 代表字符 “A” 在字符表中的位置。

計算機統一使用 Unicode 作為編碼字符集。

1.3 字符編碼 | Character Encoding Form

由於 Unicode 這個編碼字符集十分龐大,每個元素都需要用好幾個字節表示,為了節省存儲空間以及數據傳輸成本。人們使用字符編碼將 Unicode 表示的字符串轉換成字節序列

將字節序列轉換成 Unicode 編碼的過程稱為解碼(decode);將 Unicode 編碼轉換成字節序列的過程稱為編碼(encode)

記住字符編碼的目的是為了節省存儲空間以及數據傳輸成本。

常見的字符編碼有 ASCII、UTF-8、GBK等,應用最廣泛的字符編碼是 UTF-8 。



2 Python 的編碼字符集

Python 出現的時候 Unicode 的標准還沒制定好,所以 Python 2 只支持 ASCII 編碼字符集。ASCII 編碼字符集和 ASCII 字符編碼是同一個集合,也就是說 ASCII 碼是沒有進行轉換直接進行存儲的。

所以 Python 中的字符串默認只支持 ASCII 中的字符,為了支持 Unicode 字符,需要在包含 非 ASCII 碼字符的字符串前面添加 u,像這樣:

u"中文"

3 Python 的字符編碼

Python 默認支持的字符編碼也是 ASCII,一般都不夠用,我們通常希望將其編碼為 UTF-8(UTF-8 without BOM),為了實現這一目標,需要在文件頭部進行字符編碼聲明,並將文件保存為 UTF-8 格式。
字符編碼聲明必須放在文件的前兩行,聲明方式如下:

# -*- coding:utf-8 -*-

或者,

#coding=utf-8

Python 對這類聲明的格式要求比較嚴格,所在位置錯誤或者中間多添加空格都會導致聲明失效。

  • 如果未添加聲明,會出現類似這樣的錯誤 SyntaxError: Non-ASCII character '\xe4' in file .../sample.py on line 4, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

  • 如果添加了 UTF-8 的聲明,但是文件保存為 GBK 格式,會出現錯誤 [Decode error - output not utf-8]

3.1 Sublime Text 2 編譯錯誤

在 ST2 中,即使進行了正確的設置,依然會出現錯誤 UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) 。這是由於 ST2 在輸出字符串時無法識別 Python 對標准輸入輸出的編碼,而默認使用了 ASCII 編碼,解決方案是這樣的,通過 Sublime Text 2 -> Preference -> Browse Packages 找到 Python 文件夾,打開 Python.sublime-build 文件,添加一個 env 域:

"env": {"PYTHONIOENCODING": "utf8"},

另一個解決方案是在 .py 文件中對字符串進行顯式的編碼,例如:

print u"中文".encode("utf-8")

關於該問題的詳細描述參見 有關 Python 2 和 Sublime Text 中文 Unicode 編碼問題的分析與理解

4 附錄

最后添加一個例子以方便理解。

文件 Python.sublime-build

{
    "cmd": ["python2.7", "-u", "$file"],
    "path":"/System/Library/Frameworks/Python.framework/Versions/2.7/bin/",
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "env": {"PYTHONIOENCODING": "utf8"},
    "selector": "source.python"
}

文件 sample.py

#! /usr/bin/env python
#coding=utf-8

print u"你好,"
print u"我是唐衣可俊!".encode('utf-8')

輸出:

你好,
我是唐衣可俊!

參考鏈接

十分鍾搞清字符集和字符編碼(對字符集和字符編碼進行了比較系統詳盡的介紹)
有關 Python 2 和 Sublime Text 中文 Unicode 編碼問題的分析與理解(關於 ST2 對 Unicode 字符輸出報錯的問題進行了詳細的分析)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM