日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python字符集_PYTHON 中的字符集

發(fā)布時間:2025/3/21 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python字符集_PYTHON 中的字符集 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python中的字符編碼是個老生常談的話題,今天來梳理一下相關(guān)知識,希望給其他人些許幫助。

Python2的?默認(rèn)編碼?是ASCII,不能識別中文字符,需要顯式指定字符編碼;Python3的?默認(rèn)編碼?為Unicode,可以識別中文字符。

相信大家在很多文章中都看到過類似上面這樣“對Python中中文處理”的解釋,也相信大家在最初看到這樣的解釋的時候確實覺得明白了。可是時間久了之后,再重復(fù)遇到相關(guān)問題就會覺得貌似理解的又不是那么清楚了。如果我們了解上面說的默認(rèn)編碼的作用是什么,我們就會更清晰的明白那句話的含義。

需要說明的是,“字符編碼是什么”,以及“字符編碼的發(fā)展過程” 不是本節(jié)討論的話題,這些內(nèi)容可以參考我之前的?<>。

二、相關(guān)概念

1. 字符與字節(jié)

一個字符不等價于一個字節(jié),字符是人類能夠識別的符號,而這些符號要保存到計算的存儲中就需要用計算機(jī)能夠識別的字節(jié)來表示。一個字符往往有多種表示方法,不同的表示方法會使用不同的字節(jié)數(shù)。這里所說的不同的表示方法就是指字符編碼,比如字母A-Z都可以用ASCII碼表示(占用一個字節(jié)),也可以用UNICODE表示(占兩個字節(jié)),還可以用UTF-8表示(占用一個字節(jié))。字符編碼的作用就是將人類可識別的字符轉(zhuǎn)換為機(jī)器可識別的字節(jié)碼,以及反向過程。

UNICDOE才是真正的字符串,而用ASCII、UTF-8、GBK等字符編碼表示的是字節(jié)串。關(guān)于這點(diǎn),我們可以在Python的官方文檔中經(jīng)常可以看到這樣的描述"Unicode string" , " translating a Unicode string into a sequence of bytes"

我們寫代碼是寫在文件中的,而字符是以字節(jié)形式保存在文件中的,因此當(dāng)我們在文件中定義個字符串時被當(dāng)做字節(jié)串也是可以理解的。但是,我們需要的是字符串,而不是字節(jié)串。一個優(yōu)秀的編程語言,應(yīng)該嚴(yán)格區(qū)分兩者的關(guān)系并提供巧妙的完美的支持。JAVA語言就很好,以至于了解Python和PHP之前我從來沒有考慮過這些不應(yīng)該由程序員來處理的問題。遺憾的是,很多編程語言試圖混淆“字符串”和“字節(jié)串”,他們把字節(jié)串當(dāng)做字符串來使用,PHP和Python2都屬于這種編程語言。最能說明這個問題的操作就是取一個包含中文字符的字符串的長度:

對字符串取長度,結(jié)果應(yīng)該是所有字符串的個數(shù),無論中文還是英文對字符串對應(yīng)的字節(jié)串取長度,就跟編碼(encode)過程使用的字符編碼有關(guān)了(比如:UTF-8編碼,一個中文字符需要用3個字節(jié)來表示;GBK編碼,一個中文字符需要2個字節(jié)來表示)

注意:Windows的cmd終端字符編碼默認(rèn)為GBK,因此在cmd輸入的中文字符需要用兩個字節(jié)表示

>>> # Python2

>>> a = 'Hello,中國' # 字節(jié)串,長度為字節(jié)個數(shù) = len('Hello,')+len('中國') = 6+2*2 = 10

>>> b = u'Hello,中國' # 字符串,長度為字符個數(shù) = len('Hello,')+len('中國') = 6+2 = 8

>>> c = unicode(a, 'gbk') # 其實b的定義方式是c定義方式的簡寫,都是將一個GBK編碼的字節(jié)串解碼(decode)為一個Uniocde字符串>>>

>>> print(type(a), len(a))

(, 10)

>>> print(type(b), len(b))

(, 8)

>>> print(type(c), len(c))

(, 8)

>>>

Python3中對字符串的支持做了很大的改動,具體內(nèi)容會在下面介紹。

2. 編碼與解碼

先做下科普:UNICODE字符編碼,也是一張字符與數(shù)字的映射,但是這里的數(shù)字被稱為代碼點(diǎn)(code point), 實際上就是十六進(jìn)制的數(shù)字。

Python官方文檔中對Unicode字符串、字節(jié)串與編碼之間的關(guān)系有這樣一段描述:

Unicode字符串是一個代碼點(diǎn)(code point)序列,代碼點(diǎn)取值范圍為0到0x10FFFF(對應(yīng)的十進(jìn)制為1114111)。這個代碼點(diǎn)序列在存儲(包括內(nèi)存和物理磁盤)中需要被表示為一組字節(jié)(0到255之間的值),而將Unicode字符串轉(zhuǎn)換為字節(jié)序列的規(guī)則稱為編碼。

這里說的編碼不是指字符編碼,而是指編碼的過程以及這個過程中所使用到的Unicode字符的代碼點(diǎn)與字節(jié)的映射規(guī)則。這個映射不必是簡單的一對一映射,因此編碼過程也不必處理每個可能的Unicode字符,例如:

將Unicode字符串轉(zhuǎn)換為ASCII編碼的規(guī)則很簡單--對于每個代碼點(diǎn):

如果代碼點(diǎn)數(shù)值<128,則每個字節(jié)與代碼點(diǎn)的值相同如果代碼點(diǎn)數(shù)值>=128,則Unicode字符串無法在此編碼中進(jìn)行表示(這種情況下,Python會引發(fā)一個UnicodeEncodeError異常)

將Unicode字符串轉(zhuǎn)換為UTF-8編碼使用以下規(guī)則:

如果代碼點(diǎn)數(shù)值<128,則由相應(yīng)的字節(jié)值表示(與Unicode轉(zhuǎn)ASCII字節(jié)一樣)如果代碼點(diǎn)數(shù)值>=128,則將其轉(zhuǎn)換為一個2個字節(jié),3個字節(jié)或4個字節(jié)的序列,該序列中的每個字節(jié)都在128到255之間。

簡單總結(jié):

編碼(encode):將Unicode字符串(中的代碼點(diǎn))轉(zhuǎn)換特定字符編碼對應(yīng)的字節(jié)串的過程和規(guī)則

解碼(decode):將特定字符編碼的字節(jié)串轉(zhuǎn)換為對應(yīng)的Unicode字符串(中的代碼點(diǎn))的過程和規(guī)則

可見,無論是編碼還是解碼,都需要一個重要因素,就是特定的字符編碼。因為一個字符用不同的字符編碼進(jìn)行編碼后的字節(jié)值以及字節(jié)個數(shù)大部分情況下是不同的,反之亦然。

三、Python中的默認(rèn)編碼

1. Python源代碼文件的執(zhí)行過程

我們都知道,磁盤上的文件都是以二進(jìn)制格式存放的,其中文本文件都是以某種特定編碼的字節(jié)形式存放的。對于程序源代碼文件的字符編碼是由編輯器指定的,比如我們使用Pycharm來編寫Python程序時會指定工程編碼和文件編碼為UTF-8,那么Python代碼被保存到磁盤時就會被轉(zhuǎn)換為UTF-8編碼對應(yīng)的字節(jié)(encode過程)后寫入磁盤。當(dāng)執(zhí)行Python代碼文件中的代碼時,Python解釋器在讀取Python代碼文件中的字節(jié)串之后,需要將其轉(zhuǎn)換為UNICODE字符串(decode過程)之后才執(zhí)行后續(xù)操作。

上面已經(jīng)解釋過,這個轉(zhuǎn)換過程(decode,解碼)需要我們指定文件中保存的字節(jié)使用的字符編碼是什么,才能知道這些字節(jié)在UNICODE這張萬國碼和統(tǒng)一碼中找到其對應(yīng)的代碼點(diǎn)是什么。這里指定字符編碼的方式大家都很熟悉(# -*- coding:utf-8 -*-),如下所示:

2. 默認(rèn)編碼

那么,如果我們沒有在代碼文件開始的部分指定字符編碼,Python解釋器會使用哪種字符編碼把從代碼文件中讀取到的字節(jié)轉(zhuǎn)換為UNICODE代碼點(diǎn)呢?就像我們配置某些軟件時,有很多默認(rèn)選項一樣,需要在Python解釋器內(nèi)部設(shè)置默認(rèn)的字符編碼來解決這個問題,這就是文章開頭所說的“默認(rèn)編碼”。因此大家所說的Python中文字符問題就可以總結(jié)為一句話:當(dāng)無法通過默認(rèn)的字符編碼對字節(jié)進(jìn)行轉(zhuǎn)換時,就會出現(xiàn)解碼錯誤(UnicodeEncodeError)。

Python2和Python3的解釋器使用的默認(rèn)編碼是不一樣的,我們可以通過sys.getdefaultencoding()來獲取默認(rèn)編碼:

>>> # Python2

>>> import sys

>>> sys.getdefaultencoding()

'ascii'

>>> # Python3

>>> import sys

>>> sys.getdefaultencoding()

'utf-8'

因此,對于Python2來講,Python解釋器在讀取到中文字符的字節(jié)碼嘗試解碼操作時,會先查看當(dāng)前代碼文件頭部是否有指明當(dāng)前代碼文件中保存的字節(jié)碼對應(yīng)的字符編碼是什么。如果沒有指定則使用默認(rèn)字符編碼"ASCII"進(jìn)行解碼導(dǎo)致解碼失敗,導(dǎo)致如下錯誤:

SyntaxError: Non-ASCII character '\xc4' in file xxx.py on line 11, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

對于Python3來講,執(zhí)行過程是一樣的,只是Python3的解釋器以"UTF-8"作為默認(rèn)編碼,但是這并不表示可以完全兼容中文問題。比如我們在Windows上進(jìn)行開發(fā)時,Python工程及代碼文件都使用的是默認(rèn)的GBK編碼,也就是說Python代碼文件是被轉(zhuǎn)換成GBK格式的字節(jié)碼保存到磁盤中的。Python3的解釋器執(zhí)行該代碼文件時,試圖用UTF-8進(jìn)行解碼操作時,同樣會解碼失敗,導(dǎo)致如下錯誤:

SyntaxError: Non-UTF-8 code starting with '\xc4' in file xxx.py on line 11, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

3. 最佳實踐

創(chuàng)建一個工程之后先確認(rèn)該工程的字符編碼是否已經(jīng)設(shè)置為UTF-8為了兼容Python2和Python3,在代碼頭部聲明字符編碼:-*- coding:utf-8 -*-

四、Python2與Python3中對字符串的支持

其實Python3中對字符串支持的改進(jìn),不僅僅是更改了默認(rèn)編碼,而是重新進(jìn)行了字符串的實現(xiàn),而且它已經(jīng)實現(xiàn)了對UNICODE的內(nèi)置支持,從這方面來講Python已經(jīng)和JAVA一樣優(yōu)秀。下面我們來看下Python2與Python3中對字符串的支持有什么區(qū)別:

Python2

Python2中對字符串的支持由以下三個類提供

class basestring(object)

class str(basestring)

class unicode(basestring)

執(zhí)行help(str)和help(bytes)會發(fā)現(xiàn)結(jié)果都是str類的定義,這也說明Python2中str就是字節(jié)串,而后來的unicode對象對應(yīng)才是真正的字符串。

#!/usr/bin/env python# -*- coding:utf-8 -*-

a = '你好'

b = u'你好'

print(type(a), len(a))

print(type(b), len(b))

輸出結(jié)果:

(, 6)

(, 2)

Python3

Python3中對字符串的支持進(jìn)行了實現(xiàn)類層次的上簡化,去掉了unicode類,添加了一個bytes類。從表面上來看,可以認(rèn)為Python3中的str和unicode合二為一了。

class bytes(object)

class str(object)

實際上,Python3中已經(jīng)意識到之前的錯誤,開始明確的區(qū)分字符串與字節(jié)。因此Python3中的str已經(jīng)是真正的字符串,而字節(jié)是用單獨(dú)的bytes類來表示。也就是說,

Python3默認(rèn)定義的就是字符串,實現(xiàn)了對UNICODE的內(nèi)置支持,減輕了程序員對字符串處理的負(fù)擔(dān)。

#!/usr/bin/env python# -*- coding:utf-8 -*-

a = '你好'

b = u'你好'

c = '你好'.encode('gbk')

print(type(a), len(a))

print(type(b), len(b))

print(type(c), len(c))

輸出結(jié)果:

2

2

4

五、字符編碼轉(zhuǎn)換

上面提到,UNICODE字符串可以與任意字符編碼的字節(jié)進(jìn)行相互轉(zhuǎn)換,如圖:

那么大家很容易想到一個問題,就是不同的字符編碼的字節(jié)可以通過Unicode相互轉(zhuǎn)換嗎?答案是肯定的。

Python2中的字符串進(jìn)行字符編碼轉(zhuǎn)換過程是:

字節(jié)串-->decode('原來的字符編碼')-->Unicode字符串-->encode('新的字符編碼')-->字節(jié)串

#!/usr/bin/env python# -*- coding:utf-8 -*-

utf_8_a = '我愛中國'

gbk_a = utf_8_a.decode('utf-8').encode('gbk')

print(gbk_a.decode('gbk'))

輸出結(jié)果:

我愛中國

Python3中定義的字符串默認(rèn)就是unicode,因此不需要先解碼,可以直接編碼成新的字符編碼:

字符串-->encode('新的字符編碼')-->字節(jié)串

#!/usr/bin/env python# -*- coding:utf-8 -*-

utf_8_a = '我愛中國'

gbk_a = utf_8_a.encode('gbk')

print(gbk_a.decode('gbk'))

輸出結(jié)果:

我愛中國

最后需要說明的是,Unicode不是有道詞典,也不是google翻譯器,它并不能把一個中文翻譯成一個英文。正確的字符編碼的轉(zhuǎn)換過程只是把同一個字符的字節(jié)表現(xiàn)形式改變了,而字符本身的符號是不應(yīng)該發(fā)生變化的,因此并不是所有的字符編碼之間的轉(zhuǎn)換都是有意義的。怎么理解這句話呢?比如GBK編碼的“中國”轉(zhuǎn)成UTF-8字符編碼后,僅僅是由4個字節(jié)變成了6個字節(jié)來表示,但其字符表現(xiàn)形式還應(yīng)該是“中國”,而不應(yīng)該變成“你好”或者“China”。

前面花了很大的篇幅介紹概念和理論,后面注重實踐,希望對他人有所幫助。

注:

對于python3.x,由于默認(rèn)使用的是unicode,所以直接可以打印中文:

對于python2.x,由于默認(rèn)使用的是Ascii,輸出中文會報錯,所以需要在python文件開頭指定字符集:

#!/usr/bin/env python

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

第一行指定解釋器,第二行指定字符集。這就告訴python解釋器使用utf-8編碼,而utf-8是包含中文的,這樣就可以打印中文了

天帥老師博客:http://www.cnblogs.com/luotianshuai/articles/5735051.html

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的python字符集_PYTHON 中的字符集的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久国久产久精永久网页 | 噜噜噜在线 | 黄三级| 日本午夜一区二区三区 | 欧美久久久久久久久久久久久久 | 婷婷婷色 | 日韩精品视频在线观看免费 | 高清av一区| 爱蜜臀av | 中文在线a在线 | 色网站免费观看 | 丰满熟妇人妻av无码区 | 免费福利在线 | 亚州中文 | 国产黄色大片免费看 | 黄色免费在线播放 | 韩国一级片在线观看 | 日本一本二本三区免费 | 玖玖在线免费视频 | 老司机午夜福利视频 | 性色av免费 | 激情四射综合网 | 香蕉视频免费在线观看 | 色一色成人网 | 夜夜操女人 | 青青视频免费 | 欧美极品少妇×xxxbbb | 亚洲无吗视频 | 在线观看h网站 | 制服.丝袜.亚洲.中文.综合懂 | 国产在线观看免费av | 色撸撸在线 | 强乱中文字幕av一区乱码 | 性开放的欧美大片 | 潘金莲黄色一级片 | 日韩精品www | 欧美三级欧美成人高清 | 成人av图片 | 国产亚洲精品久久久久久打不开 | 久久久久久久久久久久久久久久久久久 | 国产精品国产三级国产 | 亚洲欧美日韩另类在线 | 免费黄色一级片 | 久久精品老司机 | 精品久久久久久久久久 | 男女性杂交内射妇女bbwxz | av黄色在线免费观看 | wwwwww日本| 国产精品欧美精品 | 999在线观看视频 | 日本簧片在线观看 | 女优色图 | 日韩一区二区视频在线观看 | 岳奶大又白下面又肥又黑水多 | 亚洲不卡在线 | 末路1997全集免费观看完整版 | 琪琪秋霞午夜被窝电影网 | 五月99久久婷婷国产综合亚洲 | 91久久国产精品 | 日韩亚洲一区二区三区 | 亚洲久久久久久 | 日韩成人自拍 | 天堂成人国产精品一区 | 国产成人午夜精品 | 欧美黑人三级 | av黄色在线观看 | 欧美日韩中文字幕在线播放 | 国产 中文 字幕 日韩 在线 | 亚洲高清色图 | 免费网站www在线观看 | 成人污污视频在线观看 | www.色综合 | 极品少妇xxx | www.在线观看av | 精品日韩久久 | 黄色免费视屏 | 国产精品情侣自拍 | 高清视频一区二区三区 | 撸啊撸在线视频 | 极品美女一区二区三区 | 国产福利网站 | 国产精品999999 | 日日夜夜精品视频 | 欧美日韩丝袜 | 欧美日韩视频无码一区二区三 | 福利片在线看 | 亚洲aⅴ在线 | 免费看片成人 | 欧美亚洲另类视频 | 国产女人18水真多18精品一级做 | 亚洲天堂二区 | 玖玖热在线视频 | 四虎影院在线视频 | 五月婷婷七月丁香 | 欧美日韩在线精品 | 精品一区二区在线视频 | 超碰国产一区二区三区 | 免费观看一级一片 | 午夜激情毛片 |