关于python:Pickle – 加载变量(如果存在)或创建并保存它

Pickle - Load variable if exists or create and save it

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

1
2
3
4
5
if os.path.isfile("var.pickle"):
    foo = pickle.load( open("var.pickle","rb" ) )
else:
    foo = 3
    pickle.dump( foo, open("var.pickle","wb" ) )


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

1
2
3
4
5
6
7
import pickle

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

为了可重用性,我将它放在一个函数中,避免对文件上的控制流进行错误捕获,因为它效率较低,并且我将使用上下文管理器打开文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
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

用途:

1
foo = read_or_new_pickle(path="var.pickle", default=3)

foo返回3

1
foo = read_or_new_pickle(path="var.pickle", default=4)

foo仍然返回3

诚然,下面的内容相当简短和优雅,但是太多事情可能会出错,你必须抓住一切(不相信我吗?试试这个:import io, pickle; pickle.load(io.BytesIO(b"\x00")),玩二进制):

1
2
3
4
5
6
7
8
9
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

同样的用法。但我担心的是,如果文件是空的或格式不正确的,可能无法以足够快的速度关闭该文件,以避免在第二次打开时出错。因此,使用上下文管理器:

1
2
3
4
5
6
7
8
9
10
11
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