Redis in Python:Redis 在Python2和Python3中文编码的区别
来源:互联网 发布:考试经文知乎 编辑:程序博客网 时间:2024/06/02 12:40
前言:
Python把中文字符串保存到Redis,中文字符串会被转换为字节流的形式,Python从Redis的获取的中文字符串值是以字节流的形式的,所以想要显示中文还需要解码。Python2从Redis获取的值是str类型,而Python3则是bytes类型,见下面两段代码。从下面两段代码可以看出中文字符串“计算机”在Python2是以'\xbc\xc6\xcb\xe3\xbb\xfa'形式存在的,在Python3中是以b'\xe8\xae\xa1\xe7\xae\x97\xe6\x9c\xba',也就是编码方式不一样,所以解码为中文的方式也不一样。
Python2:
>>> import redis>>> r = redis.Redis()>>> r.set('test', '计算机')True>>> r.get('test')'\xbc\xc6\xcb\xe3\xbb\xfa'>>> a = r.get('test')>>> type(a)<type 'str'>>>>
Python3:
>>> import redis>>> r = redis.Redis()>>> r.set('foo', '计算机')True>>> r.get('foo')b'\xe8\xae\xa1\xe7\xae\x97\xe6\x9c\xba'>>> a = r.get('foo')>>> type(a)<class 'bytes'>>>>
安装:
下面会用到chardet模块,安装命令:
pip install chardet
Python2解码中文:
Python2中Redis返回的字符串是str类型,所以可以通过str.decode函数来解码,解码为GB2312。
>>> import redis>>> r = redis.Redis()>>> r.set('test', '我是中文字符串')True>>> a = r.get('test')>>> t = a.decode('GB2312')>>> tu'\u6211\u662f\u4e2d\u6587\u5b57\u7b26\u4e32'>>> print(t)我是中文字符串>>>
那么我们是怎么知道要解码为GB2312而不是SB213的呢?我们可以通过chardet来检测,代码如下。从chardet.detect的返回值我们可以看到编码GB2312的置信度为0.99。
>>> import redis>>> r = redis.Redis()>>> r.set('test', '我是中文字符串')True>>> a = r.get('test')>>> import chardet>>> chardet.detect(a){'confidence': 0.99, 'encoding': 'GB2312'}>>>chardet.detect使用小技巧:
chardet.detect检测的字符串越长越准确,越短越不准确,如下面的代码short中文字符串包含三个字符,检测出来是TIS-620编码,啥玩意???而long中文字符串包含12字符串,检测出来是GB2312,置信度为0.99。
>>> import redis, chardet>>> r = redis.Redis()>>> r.set('short', '我很短')True>>> r.set('long', '我是个很长的字符串!!!')True>>> short = r.get('short')>>> long = r.get('long')>>> chardet.detect(short){'confidence': 0.5397318180542452, 'encoding': 'TIS-620'}>>> chardet.detect(long){'confidence': 0.99, 'encoding': 'GB2312'}>>>
Python3解码中文:
用同样的方法,检测出在Redis中文字符串Python3中编码为utf-8,置信度为0.99。
>>> import redis, chardet>>> r = redis.Redis()>>> r.set('foo', '喵小姐,我爱你!!!我想你了。')True>>> a = r.get('foo')>>> chardet.detect(a){'language': '', 'encoding': 'utf-8', 'confidence': 0.99}>>>知道了编码方式,那就好办了,接着上面的代码:
>>> t = a.decode('utf-8')>>> t'喵小姐,我爱你!!!我想你了。'>>>也可以这样解码:
>>> t = str(a, encoding='utf-8')>>> t'喵小姐,我爱你!!!我想你了。'>>>
脑洞大开:
上面讲的都是解码都仅仅在Python2环境中或者仅仅在Python3环境中,那么我们能不能再Python2保存中文,然后在Python3解码,或者反过来。
我们先试一下Python2保存,Python3解码:
1.先在Python2环境中执行下面的代码:
2.然后在Python3执行下面的代码,华丽丽地出错了,前面Python3解码不是说好了是utf-8编码的吗?:>>> # Py2>>> import redis>>> r = redis.Redis()>>> r.set('test', '我是在Py2保存的中文字符串')True>>>
3.肯定是打开的方式不对,对没错,就是,在解码之前我们忘了先检查编码方式了,下面的代码还是在Python3中执行,这次正确了:>>> # Py3>>> import redis>>> r = redis.Redis()>>> a = r.get('test')>>> a.decode('utf-8')Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> a.decode('utf-8')UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 0: invalid continuation byte>>>
>> # Py3>>> import redis>>> r = redis.Redis()>>> a = r.get('test')>>> ab'\xce\xd2\xca\xc7\xd4\xdaPy2\xb1\xa3\xb4\xe6\xb5\xc4\xd6\xd0\xce\xc4\xd7\xd6\xb7\xfb\xb4\xae'>>> import chardet>>> chardet.detect(a){'language': 'Chinese', 'encoding': 'GB2312', 'confidence': 0.99}>>> a.decode('GB2312')'我是在Py2保存的中文字符串'>>>
在Python3中保存中文,在Python2中解码:
1.先在Python3中执行下面的代码:
>>> # Py3>>> import redis>>> r = redis.Redis()>>> r.set('test', '我是在Py3保存的中文字符串')True>>>
2.然后在Python2中执行下面的代码,吸取了上面的教训,解码前我们先检测编码方式:
>>> # Py2>>> import redis, chardet>>> r = redis.Redis()>>> a = r.get('test')>>> chardet.detect(a){'confidence': 0.99, 'encoding': 'utf-8'}>>> t = a.decode('utf-8')>>> tu'\u6211\u662f\u5728Py3\u4fdd\u5b58\u7684\u4e2d\u6587\u5b57\u7b26\u4e32'>>> print(t)我是在Py3保存的中文字符串>>>
总结:
1.在解码Redis返回的字符前要先检测编码方式,根据检测出的编码方式来编码。
2.chardet.detect检测的字符串越长越准确,越短越不准确。
3.保存的时候是什么编码方式,解码的时候也要用这种编码方式,如在Python2中保存的中文字符串是GB2312编码方式,在Python3解码该中文字符串要用GB2312编码。
阅读全文
1 0
- Redis in Python:Redis 在Python2和Python3中文编码的区别
- python2和python3编码区别
- python2和python3编码区别
- python3和python2的区别
- python3和python2的区别
- python2和python3的区别
- python2 和Python3的区别
- python2和python3的区别
- python2和python3的区别
- Python2和Python3的区别
- python2和python3的区别
- Python2和Python3的区别
- python2和python3的区别
- python2和python3的区别
- python2 和 python3 的区别
- Python3 和 Python2的区别
- python2和python3的区别
- Python2和Python3的区别
- Android中的属性,是怎么应用到控件上的(一)
- Java猴子选王问题(约瑟夫环)
- EL表达式详解
- scala的闭包
- C 字符串的输入输出
- Redis in Python:Redis 在Python2和Python3中文编码的区别
- 421. Maximum XOR of Two Numbers in an Array
- 新生代和老年代
- 什么是OAuth授权?
- java中的Observable
- bzoj 3306: 树 dfs序+线段树
- 建模进度3
- Java随机产生月份
- poj2728:Desert King(0/1分数规划,最小比率生成树)