似乎缺少Python泡菜的元素

时间:2015-12-19 21:39:58

标签: python serialization pickle

我继承了一些python代码,使用以下代码将其输出保存到pickle:

def save_picklefile_and_close(self):
    pickle.dump({'p_index': self.p_index, 'p_val': self.p_val,
                 'z': self.z, 'w': self.w, 'nd': self.nd, 'nfg': self.nfg,
                 'lamb_scalar': self.lamb_scalar, 'PEAKSIZE': self.PEAKSIZE,
                 'N': self.N, 'S': self.S, 'F': self.F,
                 'FG': self.FG, 'q': self.q,
                 'pi': self.pi, 'phi': self.phi,
                 'p_scores': self.p_scores, 'w_scores': self.w_scores, 'z_scores': self.z_scores,
                 'likelihood': self.likelihood,
                 'p_true_val': self.p_true_val,
                 'p_true_index': self.p_true_index,
                 'w_true': self.w_true,
                 'phi_true': self.phi_true,
                 'pi_true': self.pi_true,
                 'z_true': self.z_true,
                 'z_true_per_data': self.z_true_per_data,
                 'data_for_debugging': self.data_for_debugging,
                 }, self.picklefile)
    self.picklefile.close()

这对我来说就像一个腌制的字典,其中有很多在线的例子。所有密钥都在pickle文件中,例如grep 'w_true' file.p返回一个匹配项。但是当我尝试用这段代码阅读泡菜时:

f = open('file.p')
p = pickle.load(f)
print "type=", type(p)
print "shape=", p.shape
print "w_true=", p.w_true

我得到的只是一个numpy.ndarray

type= <type 'numpy.ndarray'>
shape= (56, 147)
w_true=
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-39-83ddd085f0fd> in <module>()
      3 print "type=", type(p)
      4 print "shape=", p.shape
----> 5 print "w_true=", p.w_true

AttributeError: 'numpy.ndarray' object has no attribute 'w_true'

如何访问泡菜中的其他信息?

更新 是的,我肯定在使用同一个文件。修改后的代码:

f = open('/path/to/file.p', mode='rt')

p = pickle.load(f)
print "type=", type(p)
print "shape=", p.shape

i = 0
for line in f:
    if 'w_true' in line:
        print "line no.", i, ":", line
    i += 1

结果:

type= <type 'numpy.ndarray'>
shape= (56, 147)
line no. 7499 : sS'w_true'

但是如果 w_true,那么字符串dict(以及ndarray中的所有其他键)都不应该在文件中。{{1} }, 对?我唯一的另一个想法是,也许在pickle文件头中有什么东西会误导推特者?即也许输出代码被窃听?这是file.p

的负责人
$ head -n25 file.p 
cnumpy.core.multiarray
_reconstruct
p1
(cnumpy
ndarray
p2
(I0
tS'b'
tRp3
(I1
(I56
I147
tcnumpy
dtype
p4
(S'i4'
I0
I1
tRp5
(I3
S'<'
NNNI-1
I-1
I0
tbI00

1 个答案:

答案 0 :(得分:1)

问题是创建pickle的代码只打开了一个文件:

self.picklefile = open(picklefile_name, 'wb')

然后两次写入同一个文件。首先来到这里:

if self.is_saving_pickle:
    pickle.dump(self.x, self.picklefile) #a single numpy.ndarray

然后在这里:

def save_picklefile_and_close(self):
    pickle.dump({'p_index': self.p_index, 'p_val': self.p_val,
                 # ... snip ...
                 'data_for_debugging': self.data_for_debugging,
                 }, self.picklefile)
    self.picklefile.close()

unpickler加载file.p时,它会看到并返回第一个pickle,然后在触及第二个之前停止。当第一次写入pickle.dump()来电被注释掉时,unpickling会正确地返回第二次来电中的dict

更新:基于@Mike McKerns的评论&amp;链接,也可以多次调用pickle.load()来检索同一文件中多个pickle.dump()调用所产生的多个泡菜。