Cal*_*laf 4 python string unicode utf-8 redis
经过2个 提问有关数据类型之间的区别str和unicode,我还在疑惑在下面.
在第1区,我们看到城市的类型unicode正如我们所期望的那样.
然而在方框2中,在通过磁盘往返(redis)之后,城市的类型是str(并且表示不同).
存储在磁盘上,读入和写入的教条在某处失败了.utf-8unicodeutf-8
为什么是第二个实例type(city) str而不是unicode?
同样重要的是,这有关系吗?你关心你的变量是否unicode还是str,还是你忘却的区别只是,只要代码"做正确的事"?
# -*- coding: utf-8 -*-
# Block 1
city = u'Düsseldorf'
print city, type(city), repr(city)
# Düsseldorf <type 'unicode'> u'D\xfcsseldorf'
# Block 2
import redis
r_server = redis.Redis('localhost')
r_server.set('city', city)
city = r_server.get('city')
print city, type(city), repr(city)
# Düsseldorf <type 'str'> 'D\xc3\xbcsseldorf'
Run Code Online (Sandbox Code Playgroud)
    Ala*_*ack 12
为什么使用字符集和编码并不是教条主义 - 这是必要的.希望您已经阅读了足以理解为什么我们使用了这么多字符集.Unicode显然是前进的方向(映射了所有字符),但是如何将Unicode字符从一台机器传输到另一台机器,或者将其保存到磁盘?
我们可以使用Unicode点值,但由于Unicode点实际上是32位,因此需要将每个字符保存/传输为整个32位(也称为UTF-32).a将编码为0x00000061- 这是为一个字符浪费的很多比特.在处理大多数ASCII时,UTF-16的浪费要少一些,但UTF-8是使用最少量位的最佳折衷方案.
在代码中使用解码的Unicode显然使开发人员不必考虑编码的复杂性,例如字符数等于多少字节.
正如@JFSebastian所建议的那样,redis-py驱动程序decode_responses在Redis和Connection类上包含一个选项.设置为True客户端时,将使用该encoding选项解码响应.默认情况下encoding = utf-8.
例如
r_server = redis.Redis('localhost', decode_responses=True)
city = r_server.get('city')
# city = <type 'unicode'>
Run Code Online (Sandbox Code Playgroud)
自发现以来不再需要decode_responses.
似乎Redis驱动程序相当简单 - 如果你发送一个Unicode,它会将它转换为默认编码(大多数情况下是UTF-8).在响应时,Redis不知道编码,因此返回一个str供您解密的视频.
因此,如果在发送到Redis之前将字符串编码为UTF-8并在响应时解码为UTF-8会更安全.其他DB驱动程序更高级,因此接收和返回Unicodes.
但是,当然,你不应该用.encode()和编写你的代码.decode().常见的方法是形成"Unicode三明治",以便外部数据在输入时解码为Unicode并在输出上进行编码.那么这对你有什么用呢?包装Redis驱动程序,使其返回您想要的内容,从而将解码推回到代码的外围.
例如,它应该像下面这样简单:
class UnicodeRedis(redis.Redis):
    def __init__(self, *args, **kwargs):
        if "encoding" in kwargs:
            self.encoding = kwargs["encoding"]
        else:
            self.encoding = "utf-8"
        super(UnicodeRedis, self).__init__(*args, **kwargs)
    def get(self, *args, **kwargs):
        result = super(UnicodeRedis, self).get(*args, **kwargs)
        if isinstance(result, str):
            return result.decode(self.encoding)
        else:
            return result
Run Code Online (Sandbox Code Playgroud)
然后,您可以正常地与它进行交互,除了您可以传递一个encoding更改字符串解码方式的参数.如果未设置encoding,则此代码将采用utf-8.
例如
r_server = UnicodeRedis('localhost')
city = r_server.get('city')
Run Code Online (Sandbox Code Playgroud)
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           5965 次  |  
        
|   最近记录:  |