menu

Junjielee Blog

在平凡中坚持前行,总会遇见不凡的自己

中文编码问题

在py2中的,刚开始可能觉得编码问题影响很少,但是用得多了,发觉,编码问题无处不在,很多地方都需要考虑到,可能每一处输入的值都需要检查,处理...

join连接字符串

将列表的元素串连起来,要求元素均为字符串,如果元素是中文的,要不所有的中文是str要不所有都是unicode,且join前面元素分隔符也需要保持一致。

In [17]: ','.join(['中', '文'])
Out[17]: '\xe4\xb8\xad,\xe6\x96\x87'

In [18]: u','.join(['中', '文'])
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-18-a3bbf0047ace> in <module>()
----> 1 u','.join(['中', '文'])

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

In [22]: ','.join(['中', u'文'])
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-22-f42331afba6f> in <module>()
----> 1 ','.join(['中', u'文'])

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

In [23]: ','.join([u'中', u'文', 'ab'])
Out[23]: u'\u4e2d,\u6587,ab'

In [26]: '你'.join([u'中', u'文', 'ab'])
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-26-69e76ac7bac2> in <module>()
----> 1 '你'.join([u'中', u'文', 'ab'])

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

format格式化字符串

这个和join的使用差不多,需要是保持一致性

In [24]: '{0}'.format(u'重温')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-24-4f6b9121aefd> in <module>()
----> 1 '{0}'.format(u'重温')

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

In [25]: u'{0}'.format(u'重温')
Out[25]: u'\u91cd\u6e29'

In [28]: '{0}'.format(u'重温')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-28-4f6b9121aefd> in <module>()
----> 1 '{0}'.format(u'重温')

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

In [29]: '{0}'.format('重温')
Out[29]: '\xe9\x87\x8d\xe6\xb8\xa9'

json.dumps

json.dumps方法会将所有中文转换成unicode编码,用中文来做key是非常危险且不合法的事json.loads方法也是会输出成unicode编码,这里不是针对谁,就只针对中文...

In [31]: json.dumps({'a': u'中文'})
Out[31]: '{"a": "\\u4e2d\\u6587"}'

In [32]: json.dumps({'a': '中文'})
Out[32]: '{"a": "\\u4e2d\\u6587"}'

In [33]: json.dumps({'a': 'b'})
Out[33]: '{"a": "b"}'

In [34]: json.dumps({'中': u'b'})
Out[34]: '{"\\u4e2d": "b"}'

In [35]: json.dumps({'中': u'文'})
Out[35]: '{"\\u4e2d": "\\u6587"}'

In [38]: json.loads('{"\\u4e2d": "\\u6587"}')['中']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-38-4f371f0ebb40> in <module>()
----> 1 json.loads('{"\\u4e2d": "\\u6587"}')['中']

KeyError: '\xe4\xb8\xad'

In [39]: json.loads('{"\\u4e2d": "\\u6587"}')[u'中']
Out[39]: u'\u6587'

In [41]: json.loads('{"a": "\xe4\xb8\xad"}')   # 包括loads也会输出unicode
Out[41]: {u'a': u'\u4e2d'}

unicode 和 str 的转换

对于中文来说,使用unicodestr方法强行转换是不行的

In [54]: unicode('a')
Out[54]: u'a'

In [50]: unicode('中')    # 这样子是不行的
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-50-58c95bf960ef> in <module>()
----> 1 unicode('中')

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

In [57]: str(u'中')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-57-901bd2d8242b> in <module>()
----> 1 str(u'中')

UnicodeEncodeError: 'ascii' codec can't encode character u'\u4e2d' in position 0: ordinal not in range(128)

unicode -> str

使用encode方法(str的中文使用utf8编码储存)

In [59]: u'a'.encode('utf8')
Out[59]: 'a'

In [60]: u'中'.encode('utf8')
Out[60]: '\xe4\xb8\xad'

str -> unicode

使用decode方法

In [61]: 'a'.decode('utf8')
Out[61]: u'a'

In [62]: '中'.decode('utf8')
Out[62]: u'\u4e2d'

这时候知道encodedecode方法的作用了吧