<p>我将它放在一个可重用的函数中,避免错误捕捉文件上的控制流,因为它效率较低,我将使用上下文管理器打开文件。</p>
<pre><code>import os
import pickle
def read_or_new_pickle(path, default):
if os.path.isfile(path):
with open(path, "rb") as f:
try:
return pickle.load(f)
except Exception: # so many things could go wrong, can't be more specific.
pass
with open(path, "wb") as f:
pickle.dump(default, f)
return default
</code></pre>
<p>用法:</p>
<pre><code>foo = read_or_new_pickle(path="var.pickle", default=3)
</code></pre>
<p><code>foo</code>返回<code>3</code></p>
<pre><code>foo = read_or_new_pickle(path="var.pickle", default=4)
</code></pre>
<p>而<code>foo</code>仍然返回<code>3</code>。</p>
<p>不可否认,下面的文章很简短,很优雅,但是太多的事情可能会出错,你必须抓住所有的东西(不相信我吗?试试这个:<code>import io, pickle; pickle.load(io.BytesIO(b"\x00"))</code>并播放二进制文件):</p>
<pre><code>import pickle
def read_or_new_pickle(path, default):
try:
foo = pickle.load(open(path, "rb"))
except Exception:
foo = default
pickle.dump(foo, open(path, "wb"))
return foo
</code></pre>
<p>同样的用法。但我担心文件关闭的速度可能不够快,以避免在出现空文件或格式错误的情况下第二次打开时出错。所以使用上下文管理器:</p>
<pre><code>import pickle
def read_or_new_pickle(path, default):
try:
with open(path, "rb") as f:
foo = pickle.load(f)
except Exception:
foo = default
with open(path, "wb") as f:
pickle.dump(foo, f)
return foo
</code></pre>