Python-編碼這趟渾水

來源:互聯網
上載者:User

標籤:檔案中   lin   解釋   bin   建議   span   相互轉換   編碼規範   方法   

最近聽Alex講到python編碼,還特意用部落格講解,覺得問題嚴重了,於是翻看各種部落格,先簡單的對編碼錯誤做一個總結,其他的後續慢慢補上,還得上班、還得學習、還得寫部落格?感覺有點吃不消了。各位大神不喜勿噴啊。本人是Mac電腦,終端預設編碼格式utf-8

原文地址

Python編碼錯誤及解決辦法

字串是python中最常用的資料類型,而且很多時候會用一些不屬於ascii字元集的字元,這是就會拋出UnicodeDecodeError:ascii codec can‘t decode byte 0xc4 in position 10:oridinal not range(128)異常。這種異常在python中很容易遇到,尤其是在python2.x中

字串在python內部的表示是unicode編碼,因此,在做編碼轉換是,通常需要以unicode作為轉碼的中間編碼,即先將其他編碼的字串解碼(decode)成unicode,再從unicode編碼(encode)成另一種編碼。但是在Python2.x中預設編碼格式是ascii,就是說在沒有指定Python源碼編碼格式的情況下,源碼中所有字元都被預設為ascii碼。也是因為這個根本原因,在Python2.x中經常遇到UnicodeDecodeError或者UnicodeEncodeError的異常。

Unicode為了能夠處理Unicode資料,同時相容Python某些內部模組,Python2.x中提供了Unicode這種資料類型,通過decode和encode方法可以將其他編碼和unicode編碼相互轉換。

Python常見編碼異常(幾乎都出現在Python2.x中)

Python中常見的編碼異常包括:SyntaxError: Non-ASCII character 、UnicodeDecodeError和UnicodeEncodeError等。

1.SyntaxError: Non-ASCII character

這種異常不是很常見,但最好解決了。只要是因為Python源碼檔案中存在不屬於ascii字元,而且同時沒有聲明源碼的編碼格式,例如

#在Python2.x中,在檔案頭部沒有指定編碼格式s = ‘土耳其大騙子‘print  s#SyntaxError: Non-ASCII character ‘\xe5‘ in file /xxx/xxx/exercise-unicode.py on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

解決辦法:在檔案頭部聲明編碼格式 #!-*- encoding:utf-8 -*-或#!encoding:utf-8

Python2.x中如果不在源碼檔案首行指定編碼格式,則無法在Python源碼檔案中出現非ascii字元。這是由於Python解譯器預設將源碼認為是ascii編碼格式

2.UnicodeDecodeError

這個異常則會出現在調用decode方法時,原因是Python將其他編碼格式的字元轉化為unicode編碼,但是字元本身的編碼格式和decode傳入的編碼格式不一致,例如:


#Python2.x中
#!encoding:utf-8
s = ‘土耳其大騙子‘us = s.decode(‘gbk‘)#異常#UnicodeDecodeError: ‘gbk‘ codec can‘t decode bytes in position 4-5: illegal multibyte sequence

上面這段代碼字串字串s預設的編碼格式是“utf-8”(#!encoding:utf-8聲明的意思就是:當前.py檔案中所有的字元都是utf-8編碼的),但是在使用decode轉化為unicode編碼是傳入的編碼格式為“gbk”,因此在轉化的時候拋出UnicodeDecodeError異常。還有一種情況是在encode的時候:

#Python2.x中#! -*- encoding:utf-8 -*-s = ‘土耳其大騙子‘us = s.encode(‘gbk‘)#輸出#UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe5 in position 0: ordinal not in range(128)

這裡是s是“utf-8”編碼,直接使用s.encode(‘gbk‘),實際上是使用了系統預設的defaultencoding來解碼,等價於

s.decode(defaultencoding).encode(‘gbk‘)

而s的實際編碼和defaultencoding(python2.x預設是ascii)不同。

3.UnicodeEncodeError

錯誤的decode和encode方法會出現異常,比如使用decode方法將unicode字串轉化的時候

#! -*- encoding:utf-8 -*-s = u‘土耳其大騙子‘us = s.decode(‘utf-8‘)#輸出#UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 0-5: ordinal not in range(128)

由於在Python2.x中,字串轉化為unicode編碼的時候,可以通過unicode(‘xxx‘)、u‘xxx‘、‘xxx‘.decode(‘utf-8‘),但是本樣本是將unicode編碼的字串解碼,於是拋出“UnicodeEncodeError”異常

 

Python中編碼規範

1.遵循PEP0263原則,聲明編碼格式(推薦)

在PEP 0263 Defining Python Source Code Encodings中提出了對Python編碼問題的最基本的解決方案:在Python源碼檔案中聲明編碼格式,最常見的聲明格式如下:

#!/usr/bin/python#! -*- encoding:utf-8 -*-

表示當前.py檔案的字串編碼格式都是按照“utf-8”編碼的,不是讀取的檔案是用“utf-8”編碼讀取的

2.使用 u‘中文‘ 代替中文(Python 2.x)

s1 = ‘中文‘
s2 = u‘中文‘

Python中有以上兩種聲明字串變數的方式,它們的主要的是編碼格式的不同,其他s1的編碼格式和Python標頭檔聲明的編碼格式一致,而s2的編碼格式則是unicode。如果你聲明的字串變數中包含非ascii字元,最好使用s2的的聲明格式,這樣你可以不需要執行decode,直接對字串進行操作,可以避免出現一個異常。

注意:Python3中不存在 u‘xx‘的聲明方式。

3.Reset預設編碼

Python中出現這麼多的編碼問題的根本原因是Python 2x中的預設編碼是ascii,所以你可以通過以下的方式修改預設的編碼格式:

import syssys.setdefaultencoding(‘utf-8‘)

這種方法可以解決部分編碼問題,但是同時也會引入很多其他問題,得不償失,建議不要使用這種方式。

 

Python-編碼這趟渾水

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.