python2.7版本tuple中的中文编码问题
在处理向mysql插入中文字符的过程中,碰到这样一个问题,明明是utf-8编码的中文str ,但是到了mysql里面显示的并不是中文,而是该中文字符串的utf-8编码的十六进制形式,下面是整个解决过程。
中文字符正常情况下应该是这样的:
>>> a = '中文123'
>>> print(a)
中文123
但是你如果把一个包含中文的字符放到tuple 里面,却会变成这样:
>>> a = tuple(['中文123', 'hello'])
>>> print(a)
('\xe4\xb8\xad\xe6\x96\x87123', 'hello') # 这里按理说应该显示的是('中文123', 'hello')
中文字符显示成了编码后的十六进制形式,也就是说,\x 这个python的保留字符(用来表示它后面两个字符是十六进制值),并没有得到“正确的”解析,实际上这里是把'\xe4\xb8\xad\xe6\x96\x87' 当成一个raw strings 来处理,这里面的\x 没有任何特别的意思,就是字面的\x ,所有它后面十六进制数也都只是表面上的意思。
为什么会这样?
tuple 应该是对它里面的str 做了一个encode('string_escape') 的操作,这个操作同r''等价,意思是生成一个raw strings,官方的解释是Produce a string that is suitable as string literal in Python source code, 我们做个实验:
>>> a = '中文123'
>>> a
'\xe4\xb8\xad\xe6\x96\x87123'
>>> print(a)
中文123
>>> b = a.encode('string_escape')
>>> b
'\\xe4\\xb8\\xad\\xe6\\x96\\x87123'
>>> print(b)
\xe4\xb8\xad\xe6\x96\x87123
嗯,一切都清楚了,那么问题来了,tuple 为啥要这么干呢…暂时不知道…
解决办法
对字符做decode('string_escape')就可以了。
>>> c = b.decode('string_escape')
>>> print(c)
中文123
总结
首先,tuple 会它里面的中文字符做一个r'' 的转换,这是个坑,踩过了就不说了。
其次,知道了r''的函数写法是这样的: encode('string_escape') ,也就是说,从此以后,可以对一个变量进行r'' 操作啦。
拓展
其实还有一个unicode_escape 的编码方式
官方的解释是Produce a string that is suitable as Unicode literal in Python source code.
也就是说,将\u 这个保留字符按照字面意思去解释,也就是raw unicode话。
string_escape 和unicode_escape 都是将转义字符raw 话,将它们当做普通字符来看待,只不过前者只能针对str (编码后的字符)进行操作,后者是针对unicode字符进行操作。
>>> a = u'中文'
>>> a
u'\u4e2d\u6587'
>>> print(a)
中文
>>> b = a.encode('unicode_escape')
'\\u4e2d\\u6587'
>>> print(b)
\u4e2d\u6587
题外话
是时候转Python3了。
参考链接:
[unicode_escape和string_escape](https://docs.python.org/2/library/codecs.html)
- 原文作者:比克王国
- 原文链接:https://wgqimut.github.io/posts/python2-7%E7%89%88%E6%9C%ACtuple%E4%B8%AD%E7%9A%84%E4%B8%AD%E6%96%87%E7%BC%96%E7%A0%81%E9%97%AE%E9%A2%98/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。