Python: 将版本号和数据保存到 pickle 文件中

Python: Saving version number and data into pickle file

我正在将一些数据序列化到 pickle 文件中。不幸的是,数据的结构可能会改变。因此,我在代码中有一个静态版本号,如果数据结构发生变化,它会递增。在这种情况下,泡菜文件中的数据是无效的,应该被丢弃。

因此我试图保存一个由数据和版本号组成的元组。但是从 pickle 恢复它会引发 UnicodeDecodeError:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128)

我想知道您将如何包含版本号?将它嵌入文件路径是一种选择,但要复杂得多。这是我的代码:

#%% Create a dataframe

import pandas as pd
values = {'Latitude': {0: 47.021503365600005,
  1: 47.021503365600005,
  2: 47.021503365600005,
  3: 47.021503365600005,
  4: 47.021503365600005,
  5: 47.021503365600005},
 'Longitude': {0: 15.481974060399999,
  1: 15.481974060399999,
  2: 15.481974060399999,
  3: 15.481974060399999,
  4: 15.481974060399999,
  5: 15.481974060399999}}

df = pd.DataFrame(values)
df.head()

#%% Save the dataframe including a version number

import pickle
VERSION = 1

file_path = 'tmp.p'
with open(file_path, 'wb') as f:
    pickle.dump((df, VERSION), f)

#%% Load the dataframe including the original verison number

try:
    with open(file_path, 'r') as f:
        df, version = pickle.load(f)
except ValueError as ex:
    print (ex)
    version = -1

#%% Compare version numbers

if version != VERSION:
    print ('Version do not match')

如果你真的想使用 pickle 存储你的对象,你可以像这样在 csv 文件中存储一个元组:

with open('my_file.csv', 'w') as fd:
    writer = csv.writer(fd)
    writer.writerow([version_number, pickle.dumps(fd)])

您将只有一个文件(而不是两个,正如您在评论中所说的那样),即 csv 文件。 pickle.dumps returns 一个字符串,而 pickle.loads 从一个字符串加载对象,比较 https://docs.python.org/3/library/pickle.html#pickle.dumps and https://docs.python.org/3/library/pickle.html#pickle.loads

然后你这样读数据

with open('my_file.csv') as fd:
    reader = csv.reader(fd)
    row = csv.readrow()
    fd_class = get_fd_class_by_version(row[0])
    fd = pickle.loads(row[1])

这里 get_fd_class_by_version 是一种工厂,returns class 依赖于您存储的版本。

您用于打开文件进行读取操作的模式可能有问题。 对于写入,您使用 wb(以二进制模式写入),但对于读取,您使用 r(不以二进制模式读取,省略了 b)。

open(file_path, 'rb') as f

如果您使用 Windows。

,这可能是个问题

详情请看这里:https://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files