實際上,這段代碼所出現的問題和cPickle模塊沒什麽關系。而是Python 2顯示中文“亂碼”的問題。
Python 2中,str是8-bit string sequence(有點像Python 3中的bytes)。而Python 3中str就相當於Python 2中的unicode。
所以,
>>>?a?=?'上海'>>>?repr(a)
"'\\xc9\\xcf\\xba\\xa3'"
>>>?a?#?a中存儲的8字節轉義字符序列
'\xc9\xcf\xba\xa3'
>>>?print?a?#?輸出a,在此過程中,會對a進行解碼操作,然後輸出
上海
上例中,可以看到:
a = '上海'
a中實際存儲的是:
'\xc9\xcf\xba\xa3'
這樣壹個字節序列。它實際上是對'上海'這個unicode字符串按gbk/cp936/gb18030編碼得到的(和簡體中文Windows操作系統的默認編碼有關)。
給妳推薦壹篇博客:
/kiki113/article/details/4062063
下面是我寫的示例:
#?_*_?coding:?gbk?_*_#?Test?with?Python?2.7,?Python?3.3?on?Windows?XP
try:
import?cPickle?as?p
except:
import?pickle?as?p
address_file?=?'address.txt'
class?Human(object):
def?__init__(self,?address):
self.address?=?address
def?txl(self):
af?=?{'address':?self.address}
print(af)
print(af['address'])
f?=?open(address_file,?'wb')?#?In?python?3,?use?binary?mode.
#?In?python?2.7,?default?protocol?is?0.
#?However,?it?is?3?in?python?3.3.
p.dump(af,?f,?0)
f.close()
address?=?'上海'
print(address)
dq?=?Human(address)
dq.txl()
af?=?open(address_file,?'rb')?#
print(p.load(af))
af.close()
"""
Output
----------------------------------------
Python?2.7.6:
1.?#?-*-?coding:?utf-8?-*-
涓婃搗
{'address':?'\xe4\xb8\x8a\xe6\xb5\xb7'}
涓婃搗
{'address':?'\xe4\xb8\x8a\xe6\xb5\xb7'}
2.?#?-*-?coding:?gbk?-*-?or?#?_*_?coding:?cp936?_*_
上海
{'address':?'\xc9\xcf\xba\xa3'}
上海
{'address':?'\xc9\xcf\xba\xa3'}
Python?3.3.3:
上海
{'address':?'上海'}
上海
{'address':?'上海'}
------------------------------------------
In?Python?3.3.3:
>>>?'上海'.encode('utf-8')
b'\xe4\xb8\x8a\xe6\xb5\xb7'
>>>?_.decode('cp936')
'涓婃搗'
"""
從這個示例中可以看出,雖然把字典整個print出來不能正常解析address中的內容:
>>>?addr?=?{'addr':?'上海'}>>>?addr
{'addr':?'\xc9\xcf\xba\xa3'}
>>>?print?addr
{'addr':?'\xc9\xcf\xba\xa3'}
但是單獨打印:
>>>?addr['addr']'\xc9\xcf\xba\xa3'
>>>?print?addr['addr']?#?print?輸出之前隱含了編碼解碼操作,但為何打印整個字典時輸出不正常尚待研究
上海
壹切OK。
所以,如果真的用Python 2的話,對於該問題可以考慮手工負責編碼、解碼操作(如果使用print單獨打印地址信息,就不用這麽麻煩了,因為這些事它幫妳做了)。用Python3,就沒這麽多問題了。
最後補充壹點,pickle模塊只是提供了壹種序列化Python對象的方法。所以序列化生成的文件中和想象的不壹樣也不足為奇。正如自由de王國所說的,只要序列化後還能夠反序列化成功就行了。實際上,當protocol不是0的情況下,序列化生成的文件是二進制格式的,根本沒法用記事本直接看。