【Python】python3編碼方式encode介紹

上一篇文章介紹了計算機編碼發展歷史和編碼方式,現在我們聚焦到python語言中,在最新的Python3版本中,字符串是以Unicode編碼的,也就是說,Python的字符串支持多語言。例如:

print('我喜歡 computer'.encode('utf-8'))

解釋:print函數輸出的這句話在python裏是使用Unicode編碼的(當然它此時也在內存中,因爲它現在正被加載着...)

  • 打印結果:b'\xe6\x88\x91\xe5\x96\x9c\xe6\xac\xa2 computer'

看這個輸出十分有趣,首先,輸出是以b開頭的,說明這是一段bytes。有沒有想起上篇文章說過的utf-8是向下兼容ASCII碼的?
你看輸出中的英文computer就被原樣輸出,而ASCII碼不能識別的中文,則用utf-8編碼方式來表示,如\xe8,\x88等等。
那Unicode編碼方式用得好好的,可以直接混合輸出英文和中文等多種語言,換成utf-8輸出字符只有英文能讓我們看懂,中文變成了難以分辨的十六進制(\xe8\xbf\x99\xe5\x8f\xa5\xe8...),我們爲什麼還要有utf-8編碼方式呢?
想到這個問題說明你已經get到點了。你想,utf-8編碼方式的優點是什麼?
就是省內存啊
那麼,由於Python的字符串類型是str,在內存中以Unicode編碼的,一個字符對應若干個字節。
如果要在網絡上傳輸,或者保存到磁盤上,就需要把Unicode編碼的str變爲以字節爲單位的bytes,而通過utf-8編碼或者ASCII碼編碼生成的結果就是以字節爲單位的bytes。
這句話這麼長無非就重複一個觀點:

  • python中的str是以Unicode編碼的,如果要在網絡上傳輸,或者保存到磁盤上,就得轉換爲utf-8編碼方式。

再舉個例子:

print('I love computer'.encode('ascii'))
  • 打印結果:b'I love computer'

解釋:由於'I love computer'是純英語,所以可以用ASCII編碼。
再看:'I love computer'和'b'I love computer''有什麼不同?沒錯,多了一個b。這個b大有玄妙之處:
'I love computer'是python中的str,是以Unicode方式編碼的。
'b'I love computer''也是python中的str,但它是以ASCII碼編碼的。
同樣用utf-8編碼打印結果是一樣的,(ASCII編碼實際上可以被看成是UTF-8編碼的一部分)
好了,前面是對純英文的str進行編碼,那對中文的str編碼呢?可以對中文的str進行utf-8編碼,可以進行ASCII碼編碼嗎?

print('我喜歡 computer'.encode('ascii'))

報錯:UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

str_en = 'I love computer'
str_cn = '我喜歡 computer'
bytes_e = b'I love computer'
bytes_c = b'\xe6\x88\x91\xe5\x96\x9c\xe6\xac\xa2 computer'
#bytes_cm = b'我喜歡 computer'   # bytes can only contain ASCII literal characters.

# bytes方法進行編碼
def bytes_sample():
    bytes_en_by = bytes(str_en, encoding='utf_8')
    bytes_cn_by = bytes(str_cn, encoding='utf_8')
    print('純英文字符串轉換爲bytes:',bytes_en_by)
    print('含中文字符串轉換爲bytes:',bytes_cn_by)

# 編碼
def encode_sample():
    bytes_en = str_en.encode('utf-8')
    bytes_cn = str_cn.encode('utf-8')
    bytes_en_as = str_en.encode('ascii')
    print('utf-8純英文編碼:',bytes_en)
    print('utf-8含中文編碼:',bytes_cn)
    print('ascii純英文編碼:',bytes_en_as)
    #str_bytes= str.encode(str_cn)                   # 默認utf-8,等價於下面3個
    #str_bytes= str.encode(str_cn,'utf_8')
    #str_bytes= str.encode(str_cn,encoding='utf_8')
    str_bytes= str_cn.encode()
    print('str轉成by含中文:',str_bytes)
    #bytes_cn_as = str_cn.encode('ascii')
    #print('ascii含中文編碼,會報錯:',bytes_cn_as)

# 解碼
def decode_sample():
    str_e = bytes_e.decode('utf-8')
    str_c = bytes_c.decode('utf-8')
    str_a = bytes_e.decode('ascii')
    print('utf-8純英文解碼:',str_e)
    print('utf-8含中文解碼:',str_c)
    print('ascii純英文解碼:',str_a)


if __name__ == '__main__':
    encode_sample()
    #decode_sample()
    #bytes_sample()

注意:b後面加上字符串,可以自動轉換爲bytes類型,但是隻針對ASCII類型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章