有些事情让我有点困惑。。。在
>>> from django.core.cache import get_cache
>>>
>>> cache = get_cache('django.core.cache.backends.locmem.LocMemCache')
>>>
>>> # Set the 'content' cache key to a string
>>> cache.set('content', 'a string')
>>> cache.get('content')
'a string'
>>>
>>> class TestObj(object):
... pass
>>>
>>> a = TestObj()
>>> cache.set('content', a)
>>>
>>> # cache hasn't updated...
>>> cache.get('content')
'a string'
>>>
>>> cache.set('content', 1)
>>> # this is fine however..
>>> cache.get('content')
1
>>>
好的,缓存由于某种原因不接受对象。在
^{pr2}$这就是为什么,很明显,它碰到了pickle错误
>>> import pickle
>>> pickled = pickle.dumps(a, pickle.HIGHEST_PROTOCOL)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/usr/lib/python2.7/pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "/usr/lib/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/usr/lib/python2.7/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/usr/lib/python2.7/pickle.py", line 396, in save_reduce
save(cls)
File "/usr/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.7/pickle.py", line 748, in save_global
(obj, module, name))
PicklingError: Can't pickle <class 'TestObj'>: it's not found as __builtin__.TestObj
当然,但为什么会这样?它在python控制台中工作得很好,但在djangoshell中就不行了?在
# Works fine in python shell...
>>> import pickle
>>> class TestObj(object):
... pass
...
>>> testobj = TestObj()
>>> pickled = pickle.dumps(testobj, pickle.HIGHEST_PROTOCOL)
>>> pickled
'\x80\x02c__main__\nTestObj\nq\x00)\x81q\x01}q\x02b.'
>>>
出现这个问题是因为我试图在缓存中存储一个Mock()对象以进行测试。不知道我是不是走错了路。。。在
问题是pickle通过引用序列化类,所以您不能使用一个更好的序列化器,通过序列化类定义而不是通过引用来pickle类吗?然后将pickle一个mock对象,然后pickle类源代码,然后将其传递给django缓存。我是
dill
的作者,这是一个更好的序列化程序……也是klepto
的作者,这是一个缓存包……这正是我将任何对象存储在SQL表、磁盘或内存缓存中的方法。在基本上(不是尝试这个,而是根据我自己的缓存包的经验来猜测它的工作原理),它应该是这样工作的:
如果您想自己尝试一下,请在此处获得
dill
(和klepto
):https://github.com/uqfoundation在Martijn的帮助下,this follow-up question答案很简单:
是的。在
不能pickle Mock()对象,因为它们没有提供所模拟的顶级对象,因此pickle不知道从何处导入。由于缓存需要对对象进行pickle以存储它,因此无法在LocMemCache中存储Mock()实例。我得重新考虑我该如何测试这个。在
这是因为django LocMemCache默认使用cPickle而不是pickle。在LocMemCache类中可以看到:
如果要在shell中执行以下操作:
^{pr2}$同样的错误。在
作为可能的解决方案,我建议您在测试中使用pickle手动打包对象,然后再打包缓存.set():
相关问题 更多 >
编程相关推荐