<p>当用<code>pickle.dump(w, open("file", "wb"))</code>在<code>__main__</code>模块中pickle <code>w</code>时,<code>w</code>来自{<cd2>}模块的事实记录在<code>file</code>的第一行:</p>
<pre><code>% xxd file
0000000: 2869 5f5f 6d61 696e 5f5f 0a57 6f72 6c64 (i__main__.World
0000010: 0a70 300a 2864 7031 0a62 2e .p0.(dp1.b.
</code></pre>
<p>当IPython尝试取消拾取<code>file</code>时,它执行以下行:</p>
^{pr2}$
<p>特别是,它尝试执行<code>__import__('__main__')</code>。如果你在REPL中尝试,你会得到</p>
<pre><code>In [29]: fake=__import__('__main__')
In [32]: fake
Out[32]: <module '__main__' from '/usr/lib/pymodules/python2.6/IPython/FakeModule.pyc'>
</code></pre>
<p>这就是IPython在AttributeError中提到的<code>FakeModule</code>。在</p>
<p>如果你往里看<code>fake.__dict__</code>你会发现它不包括<code>World</code>,即使你在^{<cd13>之前或之后说<code>from test import World</code>。在</p>
<p>如果你跑了</p>
<pre><code>In [35]: fake.__dict__['World']=World
</code></pre>
<p>那么<code>pickle.load</code>将起作用:</p>
<pre><code>In [37]: w = pickle.load(open("file", "rb"))
</code></pre>
<p>可能有更干净的方法,我不知道。任何你能想到的将<code>World</code>放在<code>fake</code>命名空间中的方法都应该有效。在</p>
<p>2008年,IPython的创造者费尔南多·佩雷斯(fernandoperez)就这个问题发表了看法。他可能已经用某种方法解决了这个问题,以避免我的下流。您可能想询问IPython用户邮件列表,或者,也许更简单一些,只是不要在<code>__main__</code>名称空间内进行pickle。在</p>