1 版本差異概覽
1.1 Python 2.X:
- str(用於8位文本和二進制數據)
- unicode(用於寬字符文本)
在Python2中,通用的str類型填補了二進制數據的這一角色(特指python3中的bytes類型),因為字符串也只是字節的序列(單獨的unicode類型處理寬字符串)。
在Python2中,為了兼容性而使用b'xxx',但是它與'xxx'是相同的,並且產生一個str,並且,bytes只是str的同義詞。在Python3中,這二者都解決了bytes類型之間的差異。Python2中的u'xxx'和 U'xxx' Unicode字符串常量形式在Python3中已經取消了,而是使用'xxx'替代,因為所有的字符串都是Unicode,即便它們包含所有的ASCII字符。
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模塊模式匹配。
bytearray是bytes類型的一個變體,它是可變的並且支持原處修改。
它支持str和bytes所支持的常見的字符串操作,以及和列表相同的很多原處修改操作(例如,append和extend方法, 以及向索引賦值)。
1.3文件分類
python3中的文件I/O一般分為兩類:文本文件和二進制文件
使用建議:
1.如果正在處理圖像文件,其他程序創建的、而且必須解壓的打包數據,或者一些設 備數據流,則使用bytes和二進制模式文件處理它更合適。如果想要更新數據而不 在內存中產生其副本,也可以選擇使用bytearray。
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。
>>> 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系統編碼
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系統編碼
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。
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)
