python編碼問題在此終結

1 版本差別概覽

1.1 Python 2.X:

  • str(用於8位文本和二進制數據)
  • unicode(用於寬字符文本)

在Python2中,通用的str類型填補了二進制數據的這一角色(特指python3中的bytes類型),由於字符串也只是字節的序列(單獨的unicode類型處理寬字符串)。python

在Python2中,爲了兼容性而使用b'xxx',可是它與'xxx'是相同的,而且產生一個str,而且,bytes只是str的同義詞。在Python3中,這兩者都解決了bytes類型之間的差別。Python2中的u'xxx'和 U'xxx' Unicode字符串常量形式在Python3中已經取消了,而是使用'xxx'替代,由於全部的字符串都是Unicode,即使它們包含全部的ASCII字符。app

1.2 Python 3.X:

  • str(用於Unicode文本,包括ASCII)
  • bytes(用 於帶有絕對字節值的二進制數據)
  • bytearray(bytes的一種可變的形式)

bytes是一個不可改變的字符序列。
Python 3.0 bytes對象是較小整數的一個序列,其中每一個整數都在0到255之間。在python3中bytes主要用於處理那些沒有針對每一個任意文本格式都編碼的raw字節數據(圖像和聲音文件,以及用來與設備接口的打包數據,或者你想要用python的struct模塊處理的C程序)。Python3的bytes類型支持幾乎str類型所作的全部相同操做:這包括字符串方法、序列操做,甚至re模塊模式匹配。ide

bytearray是bytes類型的一個變體,它是可變的而且支持原處修改。
它支持str和bytes所支持的常見的字符串操做,以及和列表相同的不少原處修改操做(例如,append和extend方法, 以及向索引賦值)。ui

1.3文件分類

python3中的文件I/O通常分爲兩類:文本文件二進制文件
使用建議:
1.若是正在處理圖像文件,其餘程序建立的、並且必須解壓的打包數據,或者一些設 備數據流,則使用bytes和二進制模式文件處理它更合適。若是想要更新數據而不 在內存中產生其副本,也能夠選擇使用bytearray。this

2.若是要處理的內容實質是文本的內容,例如程序輸出、H T M L、國際化文本或 CSV或XML文件,可能要使用str和文本模式文件。編碼

2 類型轉換

Python 3.0下的類型轉換:
• str.encode()和bytes(S, encoding)把一個字符串轉換爲其raw bytes形式,而且
在此過程當中根據一個str建立一個bytes。
• bytes.decode()和str(B, encoding)把raw bytes轉換爲其字符串形式,而且在此
過程當中根據一個bytes建立一個str。url

>>> S = 'eggs' 
>>> S.encode() 
b'eggs'
>>> bytes(S, encoding='ascii') 
b'eggs'

>>> B = b'spam' 
>>> B.decode() 
'spam'
>>> str(B, encoding='ascii') 
'spam'

3 平臺默認編碼

3.1 查看系統編碼

python2系統編碼spa

Python 2.7.10 (default, Jul 30 2016, 19:40:32)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import sys
>>> sys.getdefaultencoding()
'ascii'

python3系統編碼code

Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'

3.2 修改系統編碼

若是程序執行的過程當中,遇到下面的報錯信息時,能夠把Python2的系統編碼改成utf-8。orm

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1....
#Python2的系統編碼改成utf-8,通常放在文件頭
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

4 chardet模塊

chardet是python的一個第三方庫,經常使用於編碼識別。

4.1 網頁編碼判斷:

from urllib import request
import chardet

rawdata = request.urlopen('https://www.baidu.com/').read()

tmp = chardet.detect(rawdata)
print(tmp)

"""
{'encoding': 'ascii', 'confidence': 1.0}
confidence:檢測精確度
encoding:編碼形式
"""

4.2 文件編碼判斷

import chardet

with open('text.txt', 'rb') as f:
    data = f.readline()

tmp = chardet.detect(data)
print(tmp)
"""
{'encoding': 'ascii', 'confidence': 1.0}
"""

5 源文件字符集編碼聲明

對於在腳本文件中編碼的字 符串,python默認地使用UTF-8編碼,可是,它容許咱們經過包含一個註釋來指明想要 的編碼,從而將默認值修改成支持任意的字符集。這個註釋必須擁有以下的形式,而且 在Python 2.6或Python 3.0中必須做爲腳本的第一行或第二行出現:

# -*- coding: latin-1 -*-

6 pickle序列化與編碼

pickle模塊的Python3版本老是建立一個bytes對象

>>> import pickle
>>> pickle.dumps([1, 2, 3]) 
b'\x80\x03]q\x00(K\x01K\x02K\x03e.'

>>> pickle.dumps([1, 2, 3], protocol=0)
b'(lp0\nL1L\naL2L\naL3L\na.'

序列化於反序列化(在python2與python3中都生效):

>>> import pickle
>>> pickle.dump([1, 2, 3], open('temp', 'wb')) 
>>> pickle.load(open('temp', 'rb')) 
[1, 2, 3]

7 編碼相關的其餘方法

sys/locale模塊中提供了一些獲取當前環境下的默認編碼的方法。

# coding:gbk

import sys
import locale
 
def p(f):
    print '%s.%s(): %s' % (f.__module__, f.__name__, f())
 
# 返回當前系統所使用的默認字符編碼
p(sys.getdefaultencoding)
 
# 返回用於轉換Unicode文件名至系統文件名所使用的編碼
p(sys.getfilesystemencoding)
 
# 獲取默認的區域設置並返回元祖(語言, 編碼)
p(locale.getdefaultlocale)
 
# 返回用戶設定的文本數據編碼
# 文檔提到this function only returns a guess
p(locale.getpreferredencoding)
相關文章
相關標籤/搜索