使用from __future__ import unicode_literals時要注意的問題


add by zhj: 在Python中有些庫的接口要求參數必須是str類型字符串,有些接口要求參數必須是unicode類型字符串。對於str類型的字符串,調用len()和遍歷時,其實都是以字節為單位的,這個太坑爹了,同一個字符使用不同的編碼格式,長度往往是不同的。對unicode類型的字符串調用len()和遍歷才是以字符為單位,這是我們所要的。另外,Django,Django REST framework的接口都是返回unicode類型的字符串。為了統一,我個人建議使用from __future__ import unicode_literals,將模塊中顯式出現的所有字符串轉為unicode類型,不過,對於必須使用str字符串的地方要加以注意。關於字符串類型,也是Python2坑爹的地方

 

在py2.7的項目中用了__future__模塊中的 unicode_literals 來為兼容py3.x做准備,今天遇到一個UnicodeEncodeError的錯誤,跟了下,發現這個小坑值得注意。是怎么樣的一個坑呢?跟着代碼看看。順便深究一下原理。

1. 問題

未引用unicode_literals

#coding:utf-8
from datetime import datetime

now = datetime.now()
print now.strftime('%m月%d日 %H:%M')

這段代碼正常執行,輸出: 03月12日 21:53

 

引入unicode_literals

#coding:utf-8
from __future__ import unicode_literals
from datetime import datetime

now = datetime.now()
print now.strftime('%m月%d日 %H:%M')

拋出如下錯誤:

Traceback (most recent call last):
File "unicode_error_demo2.py", line 7, in <module>
      print now.strftime('%m月%d日 %H:%M')
UnicodeEncodeError: 'ascii' codec can't encode character u'\u6708' in position 2: ordinal not in range(128)

2. 原因分析

因為datetime.strftime()只接受str類型的字符串,不接受unicode類型的字符串。

 

3. 解決方案

方案一(推薦):傳入str類型的參數

#coding:utf-8
from __future__ import unicode_literals
from datetime import datetime

now = datetime.now()
print now.strftime('%m月%d日 %H:%M'.encode('utf-8'))  # 指明str類型字符串

 

 方案二(不推薦):設置運行時編碼為utf-8

#coding:utf-8
from __future__ import unicode_literals
import sys
from datetime import datetime

reload(sys)
sys.setdefaultencoding('utf-8')

now = datetime.now()
print now.strftime('%m月%d日 %H:%M')

 

 

參考資料:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM