東西是令人費解的我有點...在測試過程中,Pickle無法在django locmem緩存中存儲對象?
>>> 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
>>>
好了,所以緩存不接受某種原因的對象。
# in locmem.py, set() method
try:
pickled = pickle.dumps(new_value, pickle.HIGHEST_PROTOCOL)
self._cache[key] = pickled
except pickle.PickleError:
pass
這將是爲什麼,這顯然擊中PickleError
>>> 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控制檯中工作得很好,但不是django shell?
# 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()對象以進行測試。不知道我是否以這種錯誤的方式去...
啊,解釋它。謝謝,我錯過了。我不認爲我可以根據你的解決方案預先醃製對象,因爲它是我測試的方法,調用cache.set()而不是我的測試。不過謝謝。 – ptr
對不起,我剛剛在python shell中嘗試了這一點,並且在使用'from django.utils.six.moves import cPickle'時沒有遇到錯誤,但是我在django shell中獲取了它。那麼使用django shell會導致這個錯誤是什麼?我不認爲這本質上是一個cPickle問題 – ptr
我不太確定它。但是這種行爲的可能原因之一可能是shell中的python版本不同,因爲django.utils.six.moves存在於python2和python3之間的兼容性(https://pythonhosted.org/six/#module-six.moves) 。要檢查它,你可以在django/core/cache/backends/locmem.py中插入「print pickle .__ file__」 –