作为源自my previous question的另一个问题,事实证明,与python shell相比,pickle在django shell中的行为有所不同......
这个脚本:
import pickle
class TestObj(object): pass
testobj = TestObj()
pickled = pickle.dumps(testobj, pickle.HIGHEST_PROTOCOL)
在python shell中可以正常工作,但是在django shell中会沿PickleError
PicklingError: Can't pickle <class 'TestObj'>: attribute lookup __builtin__.TestObj failed
有人能在这里解释这个问题吗?如果可能的话,将它链接回我之前的问题?
答案 0 :(得分:1)
pickle
将确保它可以重新导入一个类,因为只有实例本身的数据被腌制,加上类的导入位置。因此,pickle
会在类中查找__module__
属性,以确定它来自何处。
Django交互式环境似乎设置此__module__
属性;因此,TestObj.__module__
继承自object
基类,而__builtin__
。__name__
。也许没有设置pickle
全局。结果,__builtin__.TestObj
模块最终会找到您班级的错误位置。毕竟没有pickle
。
从评论中,我收集到您正在尝试将模拟对象存储在Django缓存中。这不会起作用,如mock objects are not pickleable。这是有道理的,就像 unpickling (可能是一个全新的Python过程)一样,{{1}}将如何知道原始类被嘲笑?
答案 1 :(得分:1)
你能不能只使用一个不通过引用来挑选类的序列化程序...然后预先序列化传递给django缓存的内容?这不仅会存储实例,还会存储类定义本身 - 这应该允许您在任何地方重构实例。
在原始问题上查看我的回答: Pickle can't store an object in django locmem cache during tests?
我对django Mock对象一无所知,或者对于它们有什么特别不可思议的东西......但只要它们是用python代码构建的(而不是内置的C,并且有一个很薄的python包装层),那么上面应该可行。