>>> 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'> >>>
>>> 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'> >>>
pip install chardet
Python2中Redis返回的字符串是str类型,所以可以通过str.decode函数来解码,解码为GB2312。
>>> import redis >>> r = redis.Redis() >>> r.set('test', '我是中文字符串') True >>> a = r.get('test') >>> t = a.decode('GB2312') >>> t u'\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'} >>>
>>> 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 '喵小姐,我爱你!!!我想你了。' >>>
>>> # Py2 >>> import redis >>> r = redis.Redis() >>> r.set('test', '我是在Py2保存的中文字符串') True >>>2.然后在Python3执行下面的代码,华丽丽地出错了,前面Python3解码不是说好了是utf-8编码的吗?:
>>> # Py3 >>> import redis >>> r = redis.Redis() >>> a = r.get('test') >>> a.decode('utf-8') Traceback (most recent call last): File "3.肯定是打开的方式不对,对没错,就是,在解码之前我们忘了先检查编码方式了,下面的代码还是在Python3中执行,这次正确了:", line 1, in >>>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') >>> a b'\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保存的中文字符串' >>>
>>> # Py3 >>> import redis >>> r = redis.Redis() >>> r.set('test', '我是在Py3保存的中文字符串') True >>>
>>> # 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') >>> t u'\u6211\u662f\u5728Py3\u4fdd\u5b58\u7684\u4e2d\u6587\u5b57\u7b26\u4e32' >>> print(t) 我是在Py3保存的中文字符串 >>>