Pickle - 加载变量(如果存在)或创建并保存它

Mat*_*teo 20 python serialization pickle

是否有更好的方法来加载变量,pickle如果它已经存在或创建它并转储它,如果它不存在?

if os.path.isfile("var.pickle"):
    foo = pickle.load( open( "var.pickle", "rb" ) )
else:
    foo = 3
    pickle.dump( foo, open( "var.pickle", "wb" ) )
Run Code Online (Sandbox Code Playgroud)

ale*_*cxe 29

您可以遵循EAFP原则请求宽恕:

import pickle

try:
    foo = pickle.load(open("var.pickle", "rb"))
except (OSError, IOError) as e:
    foo = 3
    pickle.dump(foo, open("var.pickle", "wb"))
Run Code Online (Sandbox Code Playgroud)


Aar*_*all 7

我把它放在一个可重用的函数中,避免错误捕获文件上的控制流,因为效率较低,我会使用上下文管理器来打开文件.

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
Run Code Online (Sandbox Code Playgroud)

用法:

foo = read_or_new_pickle(path="var.pickle", default=3)
Run Code Online (Sandbox Code Playgroud)

foo 回报 3

foo = read_or_new_pickle(path="var.pickle", default=4)
Run Code Online (Sandbox Code Playgroud)

foo仍然返回3.

不可否认,以下是相当简短和优雅,但太多的事情可能会出错,你必须抓住一切(不要相信我?试试这个:import io, pickle; pickle.load(io.BytesIO(b"\x00"))并使用二进制):

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
Run Code Online (Sandbox Code Playgroud)

相同的用法.但我担心文件可能没有足够快地关闭,以避免在文件空或格式错误时第二次打开它时出错.所以使用上下文管理器:

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
Run Code Online (Sandbox Code Playgroud)