溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

關(guān)于python2中的unicode和str以及python3中的str和bytes是怎樣的

發(fā)布時(shí)間:2021-10-14 13:59:21 來源:億速云 閱讀:133 作者:柒染 欄目:編程語言

本篇文章給大家分享的是有關(guān)關(guān)于python2中的unicode和str以及python3中的str和bytes是怎樣的,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

如果你 經(jīng)常遇到這種錯(cuò)誤提示的信息: UnicodeEncodeError: ‘a(chǎn)scii’ codec can’t encode characters in position 0-1: ordinal not in range(128), 或者杯具的發(fā)現(xiàn)明明在Eclipse中寫的程序能夠正常運(yùn)行然后到了終端下面就跳出以上的一段話.
那么, 就證明你和我一樣, 遇到了悲催的Python的編碼問題了.

之前在用Python語言寫我的畢業(yè)設(shè)計(jì), 然后各種沒有問題, 直到整個(gè)東西完成了, 突發(fā)奇想想去試一下對(duì)中文的支持. 然后你懂的, 就彈出了以上一串惡心的錯(cuò)誤提示, 然后改半天, 各種改, 各種錯(cuò)誤, 然后各種想砸鍵盤. 其實(shí)之前的一篇日志中也說到了, 解決這一類的問題最好的方法就是在程序開頭加上以下幾行代碼:

import sys
reload(sys)
sys.setdefaultencoding(“utf-8″)


那么就可助你解決幾乎95%的這種問題, 但是如果想刨根問底的話, 就需要去了解很多東西了.

首先, 這個(gè)就是Python語言本身的問題. 因?yàn)樵赑ython 2.x的語法中, 默認(rèn)的str并不是真正意義上我們理解的字符串, 而是一個(gè)byte數(shù)組, 或者可以理解成一個(gè)純ascii碼字符組成的字符串, 與Python 3中的bytes類型的變量對(duì)應(yīng); 而真正意義上通用的字符串則是unicode類型的變量,
它則與Python 3中的str變量對(duì)應(yīng). 本來應(yīng)該用作byte數(shù)組的類型, 卻被用來做字符串用, 這種看似奇葩的設(shè)定是Python 2一直被人詬病的東西, 不過也沒有辦法, 為了與之前的程序保持兼容.

在Python 2中作為兩種字符串類型, str與unicode之間就需要各種轉(zhuǎn)換的方式. 首先是一種顯式轉(zhuǎn)換的方式, 就是encode和decode兩種方法. 在這里這兩貨的意思很容易被搞反, 科學(xué)的調(diào)用方式是:

str --- decode方法 ---> unicode
unicode --- encode方法 ---> str

比如:

>>> type('x')
<type 'str'>
>>> type('x'.decode('utf-8'))
<type 'unicode'>
>>> type(u'x'.encode('utf-8'))
<type 'str'>


這個(gè)邏輯是這樣的, 對(duì)于unicode字符串使用utf-8編碼進(jìn)行編碼, 即調(diào)用encode('utf-8')方法生成byte數(shù)組類型的結(jié)果. 相反對(duì)于byte數(shù)組進(jìn)行解碼, 生成unicode字符串. 這個(gè)新手表示理解不能, 不過熟悉了就見怪不怪了.

另外是隱式的轉(zhuǎn)換, 和C語言中的int轉(zhuǎn)double類似, 當(dāng)一個(gè)unicode字符串和一個(gè)str字符串進(jìn)行連接的時(shí)候會(huì)默認(rèn)自動(dòng)將str字符串轉(zhuǎn)換成unicode類型然后再連接. 而這個(gè)時(shí)候使用的編碼方式則是系統(tǒng)所默認(rèn)的編碼方式. 使用:

import sys
print sys.getdefaultencoding()


可以得到當(dāng)前默認(rèn)的編碼方式, 是不是'ascii'? 是的話就恭喜你中彩了~!! 在這個(gè)時(shí)候如果有以下一行代碼就保證會(huì)出錯(cuò):

>>> x = u'喵'
>>> x
u'\u55b5'
>>> y = x.encode('utf-8')
>>> x + y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)


x是unicode類型的變量, y是x經(jīng)過encode后的結(jié)果是str類型的變量. x + y的時(shí)候, 首先要將y轉(zhuǎn)換成unicode字符串, 那么使用什么編碼格式轉(zhuǎn)換呢, 用utf-8還是gb2312或者還是utf-16? 這個(gè)時(shí)候就要根據(jù)sys.getdefaultencoding()來確定,
而sys.getdefaultencoding()是'ascii'編碼, 在ascii字符表中不存在0xe5這種大于128的字符存在, 所以當(dāng)然報(bào)錯(cuò)啦! 通過加入

import sys
reload(sys)
sys.setdefaultencoding(“utf-8″)


則可以將默認(rèn)的編碼轉(zhuǎn)換格式變成utf-8, 且大多數(shù)情況下, 程序中的字符串是通過utf-8來編碼的, 所以只要加上以上三行就可以了.

但是有沒有覺得, 加上這些會(huì)使得代碼有些dirty? 咳, 至少對(duì)于我來說確實(shí)很dirty. 所以我覺得平時(shí)寫程序的過程中要養(yǎng)成盡量使用顯示的轉(zhuǎn)換的習(xí)慣, 并且要明確某個(gè)函數(shù)返回的到底是str還是unicode, 凡是str的主動(dòng)decode成unicode, 不要將兩者混淆掉, 這樣寫出來的代碼才比較干凈. 此外還可以在代碼最上方加入'from
__future__ import unicode_literals'可以默認(rèn)將用戶自定義字符串變成unicode類型.
最后我想大吼一聲Python 2.x中str不是字符串, 而是BYTE數(shù)組~!

以上就是關(guān)于python2中的unicode和str以及python3中的str和bytes是怎樣的,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI