国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python 與 Unicode

Tangpj / 2569人閱讀

摘要:最近使用處理一些網絡相關的問題,被相關的一系列編碼問題搞得一頭霧水。與接下來是中對于字符串的處理。中的和在中,其類型規定了底層的數據結構,是位整數串,也即跟語言中的字符串類似。這些問題在中得到解決。

最近使用 Python 2 處理一些網絡相關的問題,被 Unicode, String 相關的一系列編碼問題搞得一頭霧水。在這里整理一下相關的概念吧。

ASCII Unicode UTF8

首先是與 Python 無關的編碼問題。在這里理清楚這幾個常見的名詞:ASCII, Unicode, UTF8 之間的關系。

我們知道,為了使用計算機處理字符,需要將字符編碼為數字。對于英文字符,128 個數字就夠了,其中最常見的英文字符編碼方案就是 ASCII,該方案規定了使用 7 位二進制數編碼英文字符的方案。

對于非英文字符,特別是漢語這種有超大字符集的語言,需要需要一個很大的編碼表將字符編碼為數字。競爭之后現在通用的方案是 Unicode,該方案的目標是覆蓋所有人類語言符號。也就是說,Unicode 定義了一個從任意字符到數字的一一映射關系。

對于 ASCII 而言,一個字符(使用 7 位編碼)占用一個字節(8 位)就夠了,可以簡單地用這個字節表示一個無符號整數來代表編碼,浪費并不大。但是對于 Unicode 而言,由于碼表太大,需要很多字節才能表示一個 Unicode 編碼數字,而且 Unicode 是一個成長中的項目,其碼表不斷擴充。因此,如何用字節表示 Unicode 編碼數字就成了一個問題,UTF-8 就是解決這個問題的方案之一。該方案是一種變長方案,使用不定長的字節表示一個數字。方案對于包含在 ASCII 碼表中的字符只使用 1 個字節進行編碼,對于非英語拼音語言符號通常使用 2 個字節編碼,漢字通常使用 3 個字節進行編碼。

如果接觸過信息論,可以很容易的理解變長編碼是如何做到的。如果讀者沒有接觸過信息論,這里展示一種簡陋的變長編碼方案,方便讀者理解。
第一個字節總是使用無符號整數表示。當數值位于 [0,254] 中時,這個字節的代表的數值就是編碼的數值。但當數值是 255 時,不表示這個數字是 255,而是表示這個數字加上之后兩位(16 bit) 代表的數之后才是編碼的數字,于是這個邊長方案能使用 1~3 字節編碼 [0, (2 ^ 16 - 1) + (2 ^ 8 - 1)] 之間的數字。

總結而言就是,Unicode 是一個字符到數字映射表,而 UTF-8 是數字到字節的編碼方案。ASCII 由于只使用一個字節,通常不太強調其數字的編碼方案。

Python 與 Unicode

接下來是 Python 中對于字符串的處理。

python 2 中的 str 和 unicode

在 Python 2 中,其 str 類型規定了底層的數據結構,是 8 位整數串,也即跟 C 語言中的字符串類似。而 unicode 類型是整數串,并不規定整數的位數或保存方式。unicode.encode() 方法在指定一種編碼方式之后返回一個 str 對象,即為這個 unicode 字符串在該編碼方式之下的字節表示。

用例子說明這個問題:

# python 2
us = u"你好"
assert(len(us) == 2)
# us 是整數串,共有兩個整數,代表兩個字符

s = us.encode("utf8")
assert(len(s) == 6)
# 使用 utf8 編碼之后,每個漢字用 3 個字節表示,共 6 個字節

僅僅是這樣,并不會引起太大的混淆。一個問題是 python 2 的字符串是可以被初始化為非英文字符的:

# python 2
s = "你好"
assert(len(s) == 6)

這種情況下解釋器會自動完成編碼工作,具體編碼方式筆者認為用戶不應該知道,而且筆者認為這種用法可能不是一種很好的用法。

更加糟糕的是,python 2 的 print 語句表現有時候會有些神奇:

# python 2
print "你好"
# 得到 你好
print u"你好"
# 得到 你好
print ["你好"]
# 得到 ["xe4xbdxa0xe5xa5xbd"]
print [u"你好"]
# 得到 [u"u4f60u597d"]

也就是,只有當直接 print str 或者 print unicode 的時候能夠正常輸出中文,其他情況下, print [str] 會輸出 "str"print [unicode] 會輸出 u"unicode"。這些打印結果看上去會讓人懷疑沒有解碼,實際上是 print 語句的行為而已。

python 3 中的 byte 和 str

在 python 2 中,str 是一種底層數據結構,類似于比特串,但 string 這個英語單詞的意思是字符串,容易引起混淆,如 unicode.encode() 返回值是一個 str,邏輯上并不恰當。

這些問題在 python 3 中得到解決。python 2 中的 str 類型相當于 python 3 中的 bytes 類型, bytes 這個名字明確的指出這是字節串,并且不指定字節串代表什么東西。而 python 3 中的 str 類似于 python 2 中的 unicode 類型, 不再指定底層編碼規則。str.encode() 返回一個 bytes 類型也更加符合邏輯。

用例子說明:

# python 3
s = "你好“
assert(len(s) == 2)

bs = s.encode("utf8")
assert(len(s) == 6)

Python 3 中的 print 函數一般總是可以正常打印 str,而不是輸出碼值。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/45545.html

相關文章

  • python編碼的意義

    摘要:而他們的中文釋義,就是對新手的最大陷阱編碼。而碼,也就是美國信息交換標準碼,年發布,位字符編碼中影響最大的一種。 編碼,還是編碼! python2的直鉤——編碼異常 當你用python打開一篇中文文檔,準備讀取里面的數據開始實驗...當你處理好你的數據,打算打印出易于閱讀的結果給boss檢查...甚至當你剛剛開始編寫自己的代碼,就寫了一句話... text = 什么鬼 只要你開始運行自...

    e10101 評論0 收藏0
  • 你真的知道Python的字符串是什么嗎?

    摘要:預告一下,下一篇你真的知道的字符串怎么用嗎將會展開介紹,敬請期待字符串序列是一種不可變序列,這意味著它不能像可變序列一能,進行就地修改。例如,在字符串的基礎上拼接,得到字符串,新的字符串是一個獨立的存在,它與基礎字符串并沒有關聯關系。 showImg(https://segmentfault.com/img/bVbjGGr?w=6016&h=4000); 在《詳解Python拼接字符串...

    Object 評論0 收藏0
  • 你真的知道Python的字符串是什么嗎?

    摘要:預告一下,下一篇你真的知道的字符串怎么用嗎將會展開介紹,敬請期待字符串序列是一種不可變序列,這意味著它不能像可變序列一能,進行就地修改。例如,在字符串的基礎上拼接,得到字符串,新的字符串是一個獨立的存在,它與基礎字符串并沒有關聯關系。 showImg(https://segmentfault.com/img/bVbjGGr?w=6016&h=4000); 在《詳解Python拼接字符串...

    Enlightenment 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<