jer*_*uki 26 python types type-conversion redis
我在我的python应用程序中使用redis来存储简单的值,如计数器和时间戳列表,但是试图获得一个计数器并将其与数字进行比较我遇到了一个问题.
如果我做:
import redis
...
myserver = redis.Redis("localhost")
myserver.set('counter', 5)
Run Code Online (Sandbox Code Playgroud)
然后尝试获得这样的值:
if myserver.get('counter') < 10:
myserver.incr('counter')
Run Code Online (Sandbox Code Playgroud)
然后我在if语句中得到一个类型错误,因为我正在比较'5'<10,这意味着我存储一个整数值并获得一个字符串(可以认为是一个不同的值).
我的问题是:这应该是那样的吗?我的意思是它是一个非常基本的类型,我理解我是否必须解析对象而不是int?似乎我做错了什么.
有什么配置我不见了?
有没有办法让redis返回正确的类型而不总是一个字符串?我这样说是因为它对于列表和日期时间甚至是浮点值都是一样的.
这可能是我正在使用的redis-py客户端的问题,而不是redis本身?
pin*_*ngz 14
正如@favoretti所说,响应回调将成功.它根本不复杂,只有一条线,所有都将被处理.
In [2]: import redis
In [3]: r = redis.Redis()
In [10]: r.set_response_callback('HGET', float)
In [11]: r.hget('myhash', 'field0')
Out[11]: 4.6
Run Code Online (Sandbox Code Playgroud)
for hmget,它返回一个字符串列表,而不是一个字符串,所以你需要构建一个更全面的回调函数:
In [12]: r.set_response_callback('HMGET', lambda l: [float(i) for i in l])
In [13]: r.hmget('myhash', 'field0')
Out[13]: [4.6]
Run Code Online (Sandbox Code Playgroud)
同样的hgetall.
小智 6
您可以将 decode_respone 设置为 True
redis.StrictRedis(host="localhost", port=6379, db=0, decode_responses=True)
Run Code Online (Sandbox Code Playgroud)
虽然利用set_response_callback对于简单数据类型来说很好,但如果您想知道存储字典、列表、元组等内容的最快和最简单的方法——并保留它们可能包含或可能不包含的 Python 原生数据类型——我推荐使用python的内置pickle库:
# Imports and simplified client setup
>>> import pickle
>>> import redis
>>> client = redis.Redis()
# Store a dictionary
>>> to_store = {'a': 1, 'b': 'A string!', 'c': [1, True, False, 14.4]}
>>> client.set('TestKey', pickle.dumps(to_store))
True
# Retrieve the dictionary you just stored.
>>> retrieved = pickle.loads(client.get('TestKey'))
{'a': 1, 'b': 'A string!', 'c': [1, True, False, 14.4]}
Run Code Online (Sandbox Code Playgroud)
这是一个简单的客户端,它将减少pickle上面示例中的样板,并为您提供一个干净的界面,用于在 Redis 中存储和检索本机 Python 数据类型:
"""Redis cache."""
import pickle
import redis
redis_host = redis.Redis()
class PythonNativeRedisClient(object):
"""A simple redis client for storing and retrieving native python datatypes."""
def __init__(self, redis_host=redis_host):
"""Initialize client."""
self.client = redis_host
def set(self, key, value, **kwargs):
"""Store a value in Redis."""
return self.client.set(key, pickle.dumps(value), **kwargs)
def get(self, key):
"""Retrieve a value from Redis."""
val = self.client.get(key)
if val:
return pickle.loads(val)
return None
redis_client = PythonNativeRedisClient()
Run Code Online (Sandbox Code Playgroud)
用法:
>>> from some_module import redis_client
>>> to_store = {'a': 1, 'b': 'A string!', 'c': [1, True, False, 14.4]}
>>> redis_client.set('TestKey', to_store)
True
>>> retrieve = redis_client.get('TestKey')
{'a': 1, 'b': 'A string!', 'c': [1, True, False, 14.4]}
Run Code Online (Sandbox Code Playgroud)
看起来这就是redis存储数据的方式:
redis 127.0.0.1:6379> set counter 5
OK
redis 127.0.0.1:6379> type counter
string
redis 127.0.0.1:6379> incr counter
(integer) 6
redis 127.0.0.1:6379> type counter
string
Run Code Online (Sandbox Code Playgroud)
如果确实愿意,您可能会猴子修补redis-py客户端以推断数据类型。