搜尋
首頁後端開發Python教學在Python中关于中文编码问题的处理建议

字符串是Python中最常用的数据类型,而且很多时候你会用到一些不属于标准ASCII字符集的字符,这时候代码就很可能抛出UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 10: ordinal not in range(128)异常。这种异常在Python中很容易遇到,尤其是在Python2.x中,是一个很让初学者费解头疼的问题。不过,如果你理解了Python的Unicode,并在编码中遵循一定的原则,这种编码问题还是比较容易理解和解决的。

字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。但是,Python 2.x的默认编码格式是ASCII,就是说,在没有指定Python源码编码格式的情况下,源码中的所有字符都会被默认为ASCII码。也因为这个根本原因,在Python 2.x中经常会遇到UnicodeDecodeError或者UnicodeEncodeError的异常。

关于Unicode

Unicode是一种字符集,它为每一种现代或古代使用的文字系统中出现的每一个字符都提供了统一的序列号,规定了符号的二进制代码,但没有规定这个二进制代码应该如何存储。也就是说:Unicode的编码方式是固定的,但是实现方式根据不同的需要有跟多种,常见的有UTF-8、UTF-16和UTF-32等。更多的介绍大家可以参看维基百科:Unicode

为了能够处理Unicode数据,同时兼容Python某些内部模块,Python 2.x中提供了Unicode这种数据类型,通过decode和encode方法可以将其它编码和Unicode编码相互转化,但同时也引入了UnicodeDecodeError和UnicodeEncodeError异常。。

常见的几种编码异常

Python中常见的几种编码异常有SyntaxError: Non-ASCII character、UnicodeDecodeError和UnicodeEncodeError等。下面依次举例说明一下:

1、SyntaxError: Non-ASCII character

这种异常最不容易出现,也最容易处理,主要原因是Python源码文件中有非ASCII字符,而且同时没有声明源码编码格式,例如:
 

s = '中文'
print s   # 抛出异常

2、UnicodeDecodeError

这个异常有时候会在调用decode方法时出现,原因是Python打算将其他编码的字符转化为Unicode编码,但是字符本身的编码格式和decode方法传入的编码格式不一致,例如:
 

#!/usr/bin/python
# -*- coding: utf-8 -*-
s = '中文'
s.decode('gb2312') # UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 2-3: illegal multibyte sequence
print s

上面这段代码中字符串s的编码格式是utf-8,但是在使用decode方法转化为Unicode编码时传入的参数是‘gb2312',因此在转化的时候抛出UnicodeDecodeError异常。还有一种情况是在encode的时候:
 

#!/usr/bin/python
# -*- coding: utf-8 -*-
s = '中文'
s.encode('gb2312') # UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
print s

3、UnicodeEncodeError

错误的使用decode和encode方法会出现这种异常,比如:使用decode方法将Unicode字符串转化的时候:
 

#!/usr/bin/python
# -*- coding: utf-8 -*-
s = u'中文'
s.decode('utf-8') # UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
print s

当然,除了上面列出的几种出现异常的情况之外还有很多可能出现异常的例子,这里就不在一一说明了。

解决方法

对于以上的几个异常,有以下几个处理的方法和原则。

1、遵循PEP0263原则,声明编码格式

在PEP 0263 -- Defining Python Source Code Encodings中提出了对Python编码问题的最基本的解决方法:在Python源码文件中声明编码格式,最常见的声明方式如下:

#!/usr/bin/python
# -*- coding: <encoding name> -*-

其中是代码所需要的编码格式,它可以是任意一种Python支持的格式,一般都会使用utf-8的编码格式。

2、使用u'中文'替代'中文'
 

str1 = '中文编码'
str2 = u'中文编码'

Python中有以上两种声明字符串变量的方式,它们的主要区别是编码格式的不同,其中,str1的编码格式和Python文件声明的编码格式一致,而str2的编码格式则是Unicode。如果你要声明的字符串变量中存在非ASCII的字符,那么最好使用str2的声明格式,这样你就可以不需要执行decode,直接对字符串进行操作,可以避免一些出现异常的情况。

3、Reset默认编码

Python中出现这么多编码问题的根本原因是Python 2.x的默认编码格式是ASCII,所以你也可以通过以下的方式修改默认的编码格式:
 

import sys
sys.setdefaultencoding('utf-8')

这种方法是可以解决部分编码问题,但是同时也会引入很多其他问题,得不偿失,不建议使用这种方式。

4、终极原则:decode early, unicode everywhere, encode late

最后分享一个终极原则:decode early, unicode everywhere, encode late,即:在输入或者声明字符串的时候,尽早地使用decode方法将字符串转化成unicode编码格式;然后在程序内使用字符串的时候统一使用unicode格式进行处理,比如字符串拼接、字符串替换、获取字符串的长度等操作;最后,在输出字符串的时候(控制台/网页/文件),通过encode方法将字符串转化为你所想要的编码格式,比如utf-8等。

按照这个原则处理Python的字符串,基本上可以解决所有的编码问题(只要你的代码和Python环境没有问题)。。。

5、升级Python 2.x到3.x

额,最后一个方法,升级Python 2.x,使用Python 3.x版本。。这样说主要是为了吐槽Python 2.x的编码设计问题。当然,升级到Python 3.x肯定可以解决大部分因为编码产生的异常问题。毕竟Python 3.x版本对字符串这部分还是做了相当大的改进的,具体的下面会说。。。。

Python 3.x中的Unicode

在Python 3.0之后的版本中,所有的字符串都是使用Unicode编码的字符串序列,同时还有以下几个改进:

1、默认编码格式改为unicode

2、所有的Python内置模块都支持unicode

3、不再支持u'中文'的语法格式

所以,对于Python 3.x来说,编码问题已经不再是个大的问题,基本上很少遇到上述的几个异常。关于Python 2.x str&unicode和Python 3.x str&bytes的更多说明和对比,大家可以看一下:Python中字符编码的总结和对比

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python中有可能理解嗎?如果是,為什麼以及如果不是為什麼?Python中有可能理解嗎?如果是,為什麼以及如果不是為什麼?Apr 28, 2025 pm 04:34 PM

文章討論了由於語法歧義而導致的Python中元組理解的不可能。建議使用tuple()與發電機表達式使用tuple()有效地創建元組。 (159個字符)

Python中的模塊和包裝是什麼?Python中的模塊和包裝是什麼?Apr 28, 2025 pm 04:33 PM

本文解釋了Python中的模塊和包裝,它們的差異和用法。模塊是單個文件,而軟件包是帶有__init__.py文件的目錄,在層次上組織相關模塊。

Python中的Docstring是什麼?Python中的Docstring是什麼?Apr 28, 2025 pm 04:30 PM

文章討論了Python中的Docstrings,其用法和收益。主要問題:Docstrings對於代碼文檔和可訪問性的重要性。

什麼是lambda功能?什麼是lambda功能?Apr 28, 2025 pm 04:28 PM

文章討論了Lambda功能,與常規功能的差異以及它們在編程方案中的效用。並非所有語言都支持他們。

什麼是休息時間,繼續並通過python?什麼是休息時間,繼續並通過python?Apr 28, 2025 pm 04:26 PM

文章討論了休息,繼續並傳遞Python,並解釋了它們在控制循環執行和程序流中的作用。

Python的通行證是什麼?Python的通行證是什麼?Apr 28, 2025 pm 04:25 PM

本文討論了Python中的“ Pass”語句,該語句是函數和類等代碼結構中用作佔位符的空操作,允許在沒有語法錯誤的情況下實現將來實現。

我們可以在Python中傳遞作為參數的函數嗎?我們可以在Python中傳遞作為參數的函數嗎?Apr 28, 2025 pm 04:23 PM

文章討論了將功能作為Python中的參數,突出了模塊化和用例(例如分類和裝飾器)等好處。

Python中的 /和//有什麼區別?Python中的 /和//有什麼區別?Apr 28, 2025 pm 04:21 PM

文章在Python中討論 /和//運營商: / for for True Division,//用於地板部門。主要問題是了解它們的差異和用例。 Character數量:158

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中