【发布时间】:2014-06-16 14:27:53
【问题描述】:
作为来自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 中会按照PicklingError: Can't pickle <class 'TestObj'>: attribute lookup __builtin__.TestObj failed 的行引发PickleError
有人能在这里解释这个问题吗?如果可能,将其链接回我之前的问题?
【问题讨论】:
-
听起来像pickle找不到Django shell中创建的
TestObj;它的环境设置与解释器略有不同。具体来说,__name__似乎有所不同。 -
有趣。那么这种行为是否也扩展到实际的 django 进程?如果您查看我之前的问题,我在测试期间很难将 Mock() 对象存储在 django 的 LocMemCache 中,并假设它是由与 shell 中发生的相同 PickleError 引起的,但也许不是?
-
不,在酸洗时,
pickle模块只存储即时数据以及再次导入类的位置。它将测试是否可以为此导入该类,并且由于似乎设置了 Django 交互式提示的方式,该测试失败(TestObj.__module__显然指向__builtin__)。 -
在常规 Django 进程中,设置不是“特殊”的。使用“可导入”的对象对此进行测试。在交互提示中,将其存储在另一个模块上,并重新指向
__module__;import somemodule、somemodule.TestObj = TestObj、TestObj.__module__ = 'somemodule'将向 Python 假装from somemodule import TestObj是重新导入类的规范方法。 -
我明白了,所以看起来我使用 Mock 得到了一个完全不同的
PicklingError,它本身就很神秘:PicklingError: Can't pickle <class 'mock.Mock'>: it's not the same object as mock.Mock