add by zhj: 在Python中有些库的接口要求参数必须是str类型字符串,有些接口要求参数必须是unicode类型字符串。对于str类型的字符串,调用len()和遍历时,其实都是以字节为单位的,这个太坑爹了,同一个字符使用不一样的编码格式,长度每每是不一样的。对unicode类型的字符串调用len()和遍历才是以字符为单位,这是咱们所要的。另外,Django,Django REST framework的接口都是返回unicode类型的字符串。为了统一,我我的建议使用from __future__ import unicode_literals,将模块中显式出现的全部字符串转为unicode类型,不过,对于必须使用str字符串的地方要加以注意。关于字符串类型,也是Python2坑爹的地方html
在py2.7的项目中用了__future__模块中的 unicode_literals 来为兼容py3.x作准备,今天遇到一个UnicodeEncodeError的错误,跟了下,发现这个小坑值得注意。是怎么样的一个坑呢?跟着代码看看。顺便深究一下原理。python
未引用unicode_literals编码
#coding:utf-8 from datetime import datetime now = datetime.now() print now.strftime('%m月%d日 %H:%M')
这段代码正常执行,输出: 03月12日 21:53spa
引入unicode_literalscode
#coding:utf-8 from __future__ import unicode_literals from datetime import datetime now = datetime.now() print now.strftime('%m月%d日 %H:%M')
抛出以下错误:htm
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)
由于datetime.strftime()只接受str类型的字符串,不接受unicode类型的字符串。blog
#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类型字符串
#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')