我已经接管了一个相当大的项目的代码。我正在尝试保存程序状态,并且有一个大型对象存储了几乎所有其他对象。我试图挑选这个对象,但是我得到了这个错误:
pickle.PicklingError:无法发现:它未被发现为内置 .module
从我在谷歌上可以找到的,这是因为某处我正在导入python init之外的东西,或者一个类属性引用了一个模块。所以,我有两个问题:
有人可以确认这就是为什么会出现这个错误的原因吗?我在代码中寻找正确的东西吗?
有没有办法找到哪一行代码/对象成员导致pickle的困难?回溯仅给出发生错误的pickle中的行,而不是被pickle对象的行。
答案 0 :(得分:11)
2)你可以将pickle.Pickler和Monkey-patch子类化,以显示它的酸洗记录。这样可以更容易地追踪问题所在。
import pickle
class MyPickler (pickle.Pickler):
def save(self, obj):
print 'pickling object', obj, 'of type', type(obj)
pickle.Pickler.save(self, obj)
这只适用于pickle.Pickler的Python实现。在Python 3.x中,pickle模块默认使用C实现,Pickler的纯Python版本称为_Pickler。
# Python 3.x
import pickle
class MyPickler (pickle._Pickler):
def save(self, obj):
print ('pickling object {0} of type {1}'.format(obj, type(obj))
pickle._Pickler.save(self, obj)
答案 1 :(得分:3)
#wrap {
background: url(http://lorempixel.com/600/400);
}
.registerWrap {
border-radius: 10px;
border: 3px solid white;
width: 45%;
height: 500px;
margin: 100px auto 40px auto;
padding: 40px;
text-align: center;
background-color: #282828;
opacity: 0.9;
filter: alpha(opacity=90);
/* For IE8 and earlier */
}
.inputbar[type=text] {
display: block;
width: 400px;
margin: 10px auto;
font-size: 18px;
padding: 10px;
-webkit-transition: all 0.40s ease-in-out;
-moz-transition: all 0.40s ease-in-out;
-ms-transition: all 0.40s ease-in-out;
-o-transition: all 0.40s ease-in-out;
outline: none;
border: 1px solid #DDDDDD;
}
.inputbar:hover {
-moz-box-shadow: 0 0 10px #ccc;
-webkit-box-shadow: 0 0 10px #ccc;
box-shadow: 0 0 10px #ccc;
}
.inputbar[type=text]:focus {
border: 1px solid #800000;
-moz-box-shadow: 0 0 1px 1px rgba(128, 0, 0, 1);
-webkit-box-shadow: 0 0 1px 1px rgba(128, 0, 0, 1);
box-shadow: 0 0 1px 1px rgba(128, 0, 0, 1);
}
#registerButton[type=submit] {
margin: 15px auto;
width: 425px;
font-size: 20px;
font-weight: bold;
padding: 14px;
cursor: pointer;
background-color: #800000;
border: none;
color: #FFFFFF;
}
#registerButton[type=submit]:hover {
-moz-box-shadow: 0 0 10px #ccc;
-webkit-box-shadow: 0 0 10px #ccc;
box-shadow: 0 0 10px #ccc;
}
中存在类似的内容。让我们看一下对象列表,看看我们能做些什么:
<div id="wrap">
<div class="registerWrap">
<form action="" method="POST">
<input type="text" class="inputbar" name="firstname" placeholder="First Name" required>
<input type="text" class="inputbar" name="lastname" placeholder="Last Name" required>
<input type="email" class="inputbaremail" name="email" placeholder="Email" required>
<input type="tel" class="inputbarphone" name="phone_number" placeholder="Cell Phone Number" required>
<input type="text" class="inputbar" name="username" placeholder="Username" autocomplete="off" required>
<input type="password" name="password" placeholder="Password" class="inputbarp" required>
<input type="password" name="password_again" placeholder="Confirm Password" class="inputbarp" required>
<label for="registerButton">
<input id="registerButton" type="submit" name="submit" value="Register">
</label>
</form>
</div>
好的,dill
无法挑选列表。那么问题是什么?
>>> import dill
>>> f = open('whatever', 'w')
>>> f.close()
>>>
>>> l = [iter([1,2,3]), xrange(5), open('whatever', 'r'), lambda x:x]
>>> dill.detect.trace(False)
>>> dill.pickles(l)
False
好的,列表中的第一项无法腌制。剩下的呢?
dill
嗯。其他物品泡好了。所以,让我们替换第一个对象。
>>> dill.detect.trace(True)
>>> dill.pickles(l)
T4: <type 'listiterator'>
False
现在我们的对象泡菜。好吧,我们可以利用一些内置的对象共享,这些共享发生在linux / unix / mac上进行酸洗......那么更强大的检查呢,比如实际在子流程中进行酸洗(就像在Windows上发生的那样)?
>>> map(dill.pickles, l)
T4: <type 'listiterator'>
Si: xrange(5)
F2: <function _eval_repr at 0x106991cf8>
Fi: <open file 'whatever', mode 'r' at 0x10699c810>
F2: <function _create_filehandle at 0x106991848>
B2: <built-in function open>
F1: <function <lambda> at 0x1069f6848>
F2: <function _create_function at 0x1069916e0>
Co: <code object <lambda> at 0x105a0acb0, file "<stdin>", line 1>
F2: <function _unmarshal at 0x106991578>
D1: <dict object at 0x10591d168>
D2: <dict object at 0x1069b1050>
[False, True, True, True]
不,该列表仍然有用......所以这是一个可以成功发送到另一个进程的对象。
现在,关于你的错误,每个人似乎都忽略了......
>>> dill.detect.trace(False)
>>> l[0] = xrange(1,4)
>>> dill.pickles(l)
True
>>> _l = dill.loads(dill.dumps(l))
对象不是pickleable,导致您的错误。
>>> dill.check(l)
[xrange(1, 4), xrange(5), <open file 'whatever', mode 'r' at 0x107998810>, <function <lambda> at 0x1079ec410>]
>>>
但是,如果我们导入ModuleType
,它就会神奇地起作用。
>>> import types
>>> types.ModuleType
<type 'module'>
>>>
>>> import pickle
>>> pickle.dumps(types.ModuleType)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
(obj, module, name))
pickle.PicklingError: Can't pickle <type 'module'>: it's not found as __builtin__.module
答案 2 :(得分:2)
作为查找对象的哪个属性/成员导致问题的快速方法,您可以尝试:
for k, v in massiveobject.__dict__.iteritems():
print k
pickle.dumps(v)
答案 3 :(得分:1)
1)与您的发现略有不同。这是一个引用模块类型(不是模块直接)的变量(类属性,列表或dict项,它可能是任何东西)引起的问题。此代码应重现此问题:
import pickle
pickle.dumps(type(pickle))