最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文教你解決所有Python中文亂碼問題

 更新時(shí)間:2023年12月07日 15:41:25   作者:Lorin洛林  
我們在編寫代碼時(shí)總是遇到各種中文亂碼的問題,所以本文就來為大家總結(jié)一下遇到的中文亂碼問題和對應(yīng)的解決方案,以及為什么會出現(xiàn)中文亂碼的問題,希望對大家有所幫助

前言

最近偶爾會幫忙寫一些爬蟲代碼,有一些需要使用 Python 編寫,因此又拾起了很久沒有寫的 Python,讓我無語的是總是遇到各種中文亂碼的問題,所以趁著周末,總結(jié)一下遇到的中文亂碼問題和對應(yīng)的解決方案,以及為什么會出現(xiàn)中文亂碼的問題。

你可能遇到下列的各種問題:

  • 1、SyntaxError: Non-ASCII character '\xe4' in file XXX
  • 2、UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 0: ordinal not in range(128)
  • 3、......

先聊聊字符編碼

  • 當(dāng)我們處理文本時(shí),字符編碼是一個(gè)關(guān)鍵的概念。字符編碼是一種將字符映射到數(shù)字表示的方式。在計(jì)算機(jī)中,文本通常以數(shù)字的形式存儲和處理,而字符編碼就是定義這種映射關(guān)系的規(guī)則。
  • 在選擇字符編碼時(shí),需要考慮存儲空間、兼容性和處理效率等因素。UTF-8 目前是使用最廣泛的字符編碼,因?yàn)樗诩嫒菪院凸?jié)省空間方面都有良好的表現(xiàn)。下面對常用的編碼做一個(gè)簡單的介紹:

ASCII(American Standard Code for Information Interchange)

ASCII 是一種最早的字符編碼,它使用 7 位二進(jìn)制數(shù)字(0 到 127)表示常用的字符,包括字母、數(shù)字、標(biāo)點(diǎn)符號和一些控制字符。由于只使用 7 位,ASCII 編碼總共可以表示 128 個(gè)字符。

Unicode

為了解決 ASCII 編碼的局限性,Unicode 應(yīng)運(yùn)而生。Unicode 是一個(gè)更為龐大的字符集,它包括世界上幾乎所有的字符,符號和標(biāo)點(diǎn)。每個(gè)字符都被分配一個(gè)唯一的數(shù)字,這個(gè)數(shù)字可能是 16 位(UCS-2)或者 32 位(UCS-4)。然而,Unicode 的缺點(diǎn)在于它需要更多的存儲空間。

UTF-8(Unicode Transformation Format - 8-bit)

為了解決 Unicode 存儲空間的問題,出現(xiàn)了 UTF-8 編碼。UTF-8 使用不定長度的編碼方案,能夠根據(jù)字符的不同使用 1 到 4 個(gè)字節(jié)表示一個(gè)字符。它保留了與 ASCII 兼容的部分,因此可以在現(xiàn)有的 ASCII 系統(tǒng)中無縫使用,并且在表示非常用字符時(shí)能夠更加節(jié)省空間。

UTF-16

UTF-16 是 Unicode 的一種實(shí)現(xiàn)方式,使用 16 位編碼方案,每個(gè)字符使用 2 個(gè)字節(jié)表示。UTF-16 的一個(gè)特點(diǎn)是在表示一些非常用字符時(shí)可能會使用額外的一個(gè)或兩個(gè)字節(jié)。

UTF-32

UTF-32 是 Unicode 的一種實(shí)現(xiàn)方式,使用 32 位編碼方案,每個(gè)字符使用 4 個(gè)字節(jié)表示。UTF-32 的特點(diǎn)是每個(gè)字符都使用相同的固定長度,方便在字符串中進(jìn)行隨機(jī)訪問。

分析中文亂碼、編碼問題的原因

從上面我們其實(shí)已經(jīng)大概可以知道我們中文亂碼、編碼問題的罪魁禍?zhǔn)祝壕幋a方式不匹配。下面我將對一些常見的案例進(jìn)行分析以及提供一些常見的解決方案。

常見案例

Python 版本 2.7

案例一

看一下下面兩個(gè)例子:.py 文件的編碼格式為UTF-8,Python2默認(rèn)使用ASCII解碼:

# 例一
s = "hello"
print s

// 正常執(zhí)行
hello

# 例二
s = "你好"
print s

// 執(zhí)行失敗
SyntaxError: Non-ASCII character '\xe4' in file XXX
  • 有些同學(xué)可能會比較疑惑,同樣是編碼格式不匹配,為什么例一可以正常執(zhí)行,而例二執(zhí)行失敗。
  • 這是因?yàn)椋?code>UTF-8 是一種向后兼容的編碼方式。如果文件中只包含 ASCII 字符,那么該文件符合 UTF-8 編碼規(guī)范。這種特性使得使用 UTF-8 編碼時(shí),與使用 ASCII 編碼的現(xiàn)有系統(tǒng)可以很好地協(xié)同工作。
  • 例一由于文件中只包含 ASCII 字符,即使使用 UTF-8 編碼,編碼結(jié)果和 ASCII 編碼一致,當(dāng)然也可以使用 ASCII 正常解碼。

解決方案

指定文件的編碼格式,讓執(zhí)行器使用指定的編碼方式解析文件。

# coding=utf-8

s = "你好"
print s

# 正常執(zhí)行
#你好

參考

PEP 263 – Defining Python Source Code Encodings

案例二

我們看一下下面的代碼:

# coding=utf-8
import xlwt

comment_list = [["標(biāo)題", "序號"], [1, 2]]

code = "1234"

# Create a new workbook and add a sheet
workbook = xlwt.Workbook()
sheet = workbook.add_sheet('Sheet1')

for row_index, row_data in enumerate(comment_list):
    for col_index, cell_data in enumerate(row_data):
        sheet.write(row_index, col_index, cell_data)

workbook.save('./%s.xls' % code)

#程序執(zhí)行報(bào)錯(cuò)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
'ascii' 無法解碼字節(jié) 0xe6 (UTF-8中的中文字符)
#如果寫入的數(shù)據(jù)中沒有中文數(shù)據(jù)是可以正常執(zhí)行的

原因

#我們看下這個(gè)對象的構(gòu)造器:workbook = xlwt.Workbook() 可以看到默認(rèn)使用的是 ascii 編碼,而我們傳入的數(shù)據(jù)是 UTF-8 (包含中文字符),因此無法解析

    #################################################################
    ## Constructor
    #################################################################
    def __init__(self, encoding='ascii', style_compression=0):
        self.encoding = encoding
        self.__owner = 'None'
        self.__country_code = None # 0x07 is Russia :-)
        self.__wnd_protect = 0
        self.__obj_protect = 0

解決方案

從上面我們已經(jīng)知道是編碼不一致的原因,因此我們只需要將Workbook編碼調(diào)整為相同即可,比如調(diào)整為utf-8:

# coding=utf-8
import xlwt

comment_list = [["標(biāo)題", "序號"], [1, 2]]

code = "1234"

# Create a new workbook and add a sheet
workbook = xlwt.Workbook(encoding="utf-8")
sheet = workbook.add_sheet('Sheet1')

for row_index, row_data in enumerate(comment_list):
    for col_index, cell_data in enumerate(row_data):
        sheet.write(row_index, col_index, cell_data)

workbook.save('./%s.xls' % code)

這里如果你不想用 utf-8 編碼,你想用 gbk 編碼怎么實(shí)現(xiàn)呢?其實(shí)中心思想是相同的,只要保證編碼格式一致即可:

# coding=utf-8
import sys
import xlwt

comment_list = [["標(biāo)題", "續(xù)保"], [1, 2]]

print "default encoding:", sys.getdefaultencoding()

# Create a new workbook and add a sheet
workbook = xlwt.Workbook(encoding="gbk")
sheet = workbook.add_sheet('Sheet1')

for row_index, row_data in enumerate(comment_list):
    for col_index, cell_data in enumerate(row_data):
        sheet.write(row_index, col_index, str(cell_data).decode("utf-8"))

code = "1234"
workbook.save('./%s.xls' % code)

#程序執(zhí)行正常
default encoding: ascii

Python2 字符串的兩種表現(xiàn)形式

可能有朋友對上述案例中使用 gbk 方式中這段代碼 str(cell_data).decode("utf-8") 有點(diǎn)疑惑,這其實(shí)涉及到 Python2 字符串的兩種表現(xiàn)形式。

字節(jié)序列 和 Unicode 對象

在 Python 2 中,字符串類型被設(shè)計(jì)為字節(jié)序列而不是 Unicode 對象。這是 Python 2 與 Python 3 之間最重要的差異之一。在 Python 2 中,有兩種主要的字符串類型:

#1、str: 表示字節(jié)序列,是原始的字節(jié)串,而不涉及字符編碼。
#2、unicode: 表示 Unicode 字符串,用于處理字符編碼和文本

#示例:
# 在 Python 2 中,默認(rèn)創(chuàng)建的是字節(jié)串而不是 Unicode 字符串
byte_str = "Hello, World!"
print type(byte_str)  # 輸出 <type 'str'>

# 創(chuàng)建 Unicode 字符串
unicode_str = u"你好"
print type(unicode_str)  # 輸出 <type 'unicode'>

字節(jié)序列 和 Unicode 對象相互轉(zhuǎn)換

# 從 str 轉(zhuǎn)換成 unicode
print byte_str.decode('utf-8')

# 從 unicode 轉(zhuǎn)換成 str
print unicode_str.encode('utf-8')

有朋友也許很奇怪,為什么從 strunicode 使用 decode,而 unicode 轉(zhuǎn)換成 str 使用 encode,其實(shí)這是因?yàn)?Python 認(rèn)為 16 位的 unicode 才是字符的唯一內(nèi)碼,而大家常用的字符集如 gb2312,gb18030/gbk,utf-8,以及 ascii 都是字符的二進(jìn)制(字節(jié))編碼形式。因此從 unicode 到其它二進(jìn)制編碼格式都使用 encode。

字符串運(yùn)算

在進(jìn)行同時(shí)包含 str 與 unicode 的運(yùn)算時(shí),Python 一律都把 str 轉(zhuǎn)換成 unicode 再運(yùn)算,當(dāng)然運(yùn)算結(jié)果也是 unicode。

str(cell_data).decode("utf-8") 寫法的原因

# 轉(zhuǎn)換為 str 類型
str(cell_data)

# 這里為什么么需要先 decode("utf-8") 轉(zhuǎn)為 unicode
# 實(shí)際上 Python 運(yùn)行時(shí)并不知道 str 的編碼,因此需要開發(fā)者指定正確的編碼方式進(jìn)行解碼
# 如果開發(fā)者不指定編碼方式進(jìn)行手動解碼則會使用 sys.getdefaultencoding() 配置的值 ascii 進(jìn)行解碼
str(cell_data).decode("utf-8")

# 由于我們在程序開頭指定了編碼方式為 utf-8 即 str 的編碼格式,如果這樣寫:
sheet.write(row_index, col_index, cell_data)
#程序執(zhí)行異常:
#UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)

#因?yàn)?ascii 編碼無法解析帶有中文的 utf-8 編碼

案例三

案例三我們來聊聊,有關(guān)控制臺打印亂碼的問題。

上面的示例中,控制臺的編碼方式為 gbk,當(dāng)按照 utf-8 字符集打印時(shí),控制臺無法解析,出現(xiàn)亂碼。

實(shí)際上我們打印控制臺時(shí),實(shí)際上打印的是字符串的字符集編碼,但一般情況會根據(jù)系統(tǒng)的字符集設(shè)置來將字符編碼輸出到控制臺。如果出現(xiàn)打印亂碼,說明字符集匹配失敗或控制臺不支持該編碼格式,我們可以根據(jù)實(shí)際情況進(jìn)行確認(rèn)。

總結(jié)

本文從 Python2.7 中出現(xiàn)的一些亂碼案例出發(fā),從字符編碼、Python2.7字符原理分析了中文亂碼、編碼問題導(dǎo)致的原因并給出相應(yīng)的解決方案,實(shí)際上在編碼亂碼分析這一塊在其它語言上也是共通的,可以作為一定的參考依據(jù)。

在 Python 3 中,字符串默認(rèn)是 Unicode 類型,這樣可以更容易地處理文本數(shù)據(jù)。由于 Python 2 已于 2020 年停止維護(hù),建議在可能的情況下遷移到 Python 3,以便利用更現(xiàn)代和更直觀的字符串處理方式。

一些建議:

1、Python3 以前使用字符串,建議都帶上前綴u,在 Python 3 中,字符串默認(rèn)是 Unicode。Unicode 支持編碼自動轉(zhuǎn)換。

比如同樣是上文的案例,你不再需要解碼

# coding=utf-8
import sys
import xlwt

comment_list = [[u"標(biāo)題", u"續(xù)保"], [1, 2]]

print "default encoding:", sys.getdefaultencoding()

# Create a new workbook and add a sheet
workbook = xlwt.Workbook(encoding="gbk")
sheet = workbook.add_sheet('Sheet1')

for row_index, row_data in enumerate(comment_list):
    for col_index, cell_data in enumerate(row_data):
        sheet.write(row_index, col_index, cell_data)

code = "1234"
workbook.save('./%s.xls' % code)

2、不要用str()函數(shù),使用unicode()代替。

3、不要用過時(shí)的 string 模塊(string 模塊已經(jīng)停止了更新,只保留了 ASCII 碼的支持,不再推薦使用,Python 保留該模塊僅僅是為了向后兼容)

4、非必要時(shí),不需要對 unicode 字符進(jìn)行編碼,因?yàn)榇蠖鄶?shù)情況會自動編碼解碼。

到此這篇關(guān)于一文教你解決所有Python中文亂碼問題的文章就介紹到這了,更多相關(guān)Python中文亂碼解決內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python使用內(nèi)置json模塊解析json格式數(shù)據(jù)的方法

    Python使用內(nèi)置json模塊解析json格式數(shù)據(jù)的方法

    這篇文章主要介紹了Python使用內(nèi)置json模塊解析json格式數(shù)據(jù)的方法,結(jié)合實(shí)例形式分析了Python使用內(nèi)置的json模塊實(shí)現(xiàn)json格式數(shù)據(jù)的解析、轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • Python中動態(tài)創(chuàng)建類實(shí)例的方法

    Python中動態(tài)創(chuàng)建類實(shí)例的方法

    在Java中我們可以通過反射來根據(jù)類名創(chuàng)建類實(shí)例,那么在Python我們怎么實(shí)現(xiàn)類似功能呢?其實(shí)在Python有一個(gè)builtin函數(shù)import,我們可以使用這個(gè)函數(shù)來在運(yùn)行時(shí)動態(tài)加載一些模塊
    2017-03-03
  • Python中時(shí)間datetime的處理與轉(zhuǎn)換用法總結(jié)

    Python中時(shí)間datetime的處理與轉(zhuǎn)換用法總結(jié)

    今天小編就為大家分享一篇關(guān)于Python中時(shí)間datetime的處理與轉(zhuǎn)換用法總結(jié),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • 對python操作kafka寫入json數(shù)據(jù)的簡單demo分享

    對python操作kafka寫入json數(shù)據(jù)的簡單demo分享

    今天小編就為大家分享一篇對python操作kafka寫入json數(shù)據(jù)的簡單demo,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • Python實(shí)現(xiàn)的txt文件去重功能示例

    Python實(shí)現(xiàn)的txt文件去重功能示例

    這篇文章主要介紹了Python實(shí)現(xiàn)的txt文件去重功能,涉及Python針對txt文本文件的讀寫、字符串遍歷、判斷相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • python 簡單搭建阻塞式單進(jìn)程,多進(jìn)程,多線程服務(wù)的實(shí)例

    python 簡單搭建阻塞式單進(jìn)程,多進(jìn)程,多線程服務(wù)的實(shí)例

    下面小編就為大家?guī)硪黄猵ython 簡單搭建阻塞式單進(jìn)程,多進(jìn)程,多線程服務(wù)的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • python繪制分布折線圖的示例

    python繪制分布折線圖的示例

    這篇文章主要介紹了python繪制分布折線圖的示例代碼,幫助大家更好的利用python繪制圖像,感興趣的朋友可以了解下
    2020-09-09
  • python實(shí)現(xiàn)socket簡單通信的示例代碼

    python實(shí)現(xiàn)socket簡單通信的示例代碼

    這篇文章主要介紹了python實(shí)現(xiàn)socket簡單通信的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 如何分離django中的媒體、靜態(tài)文件和網(wǎng)頁

    如何分離django中的媒體、靜態(tài)文件和網(wǎng)頁

    這篇文章主要介紹了如何分離django中的媒體、靜態(tài)文件和網(wǎng)頁,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Django異步任務(wù)線程池實(shí)現(xiàn)原理

    Django異步任務(wù)線程池實(shí)現(xiàn)原理

    這篇文章主要介紹了Django異步任務(wù)線程池實(shí)現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12

最新評論

鸡东县| 邹平县| 乌苏市| 四会市| 彭泽县| 临猗县| 碌曲县| 宜兴市| 大洼县| 盘山县| 阳曲县| 宜君县| 滁州市| 庄河市| 崇信县| 邹平县| 皮山县| 佳木斯市| 胶州市| 南安市| 合阳县| 方正县| 青海省| 奈曼旗| 七台河市| 临漳县| 铜川市| 江孜县| 广宁县| 富锦市| 辛集市| 和田县| 衡阳市| 新昌县| 中阳县| 新龙县| 岢岚县| 娄底市| 武川县| 仙游县| 定州市|