redis / python中的元组:可以存储,而不是检索

时间:2013-05-21 01:18:59

标签: python redis

所以,我有redis使用python - 令人兴奋!

我需要存储一个元组并在以后检索它/解析它。下面的构造不起作用,我认为因为返回的元组被引用 - 它的两端都有引号。

在我看来,引号表明它实际上不是一个元组,而是一个字符串。

那么有谁知道如何让redis真正返回一个工作元组?谢谢!

>>> tup1 = ('2011-04-05', 25.2390232323, 0.32093240923490, 25.239502352390)
>>> r.lpush('9999', tup1)
1L
>>> r.lpop('9999')
"('2011-04-05', 25.2390232323, 0.3209324092349, 25.23950235239)"
>>> v = r.lpop('9999')
>>> test=v[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object has no attribute '__getitem__'

3 个答案:

答案 0 :(得分:10)

如果你想让元组回来,我推荐使用'pickle'。

>>> tup1 = ('2011-04-05', 25.2390232323, 0.32093240923490, 25.239502352390)
>>> import pickle
>>> r.lpush('9999', pickle.dumps(tup1))
1L
>>> v = pickle.loads(r.lpop('9999'))
>>> v
('2011-04-05', 25.2390232323, 0.3209324092349, 25.23950235239)
>>> type(v)
<type 'tuple'>
>>> 

答案 1 :(得分:2)

我会选择karthikr的解决方案,但通常建议使用标准库中的literal_eval作为安全替代方案,因为eval可以执行任意代码,如果你给它搞笑输入

>>> tup1 = "print('Dont use eval! ' * 2)"
>>> r.lpush('9999', tup1)
>>> v = r.lpop('9999')
>>> test = eval(v)
Dont use eval! Dont use eval!

literal_eval会创建你的元组(或列表或字典),但不会运行函数。

>>> from ast import literal_eval
>>> tup1 = ('2011-04-05', 25.2390232323, 0.32093240923490, 25.239502352390)
>>> tup2 = "print('Dont use eval! ' * 2)"
>>> r.lpush('9999', tup2, tup1)
>>> v1 = r.lpop('9999')
>>> print(literal_eval(v1) == tup1)
True

>>> literal_eval(r.lpop('9999'))  # ==> SyntaxError: invalid syntax

答案 2 :(得分:1)

您已经popped和来自v的元素,并且您尝试检索的元素不再存在。

试试这个:

>>> tup1 = ('2011-04-05', 25.2390232323, 0.32093240923490, 25.239502352390)
>>> r.lpush('9999', tup1)
>>> v = r.lpop('9999')
>>> test = eval(v)[0]

由于返回类型是字符串,因此需要eval来评估类型