python:pickle在django shell中行为不端而不是python shell?

时间:2014-06-16 14:27:53

标签: python django pickle

作为源自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

有人能在这里解释这个问题吗?如果可能的话,将它链接回我之前的问题?

2 个答案:

答案 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包装层),那么上面应该可行。