5

shelve我一直在使用 Python 的模块(在 OSX 10.9.5 上使用 Python 3.4)将一堆字典保存到文件中。每个key都是 int 的字符串(例如,"84554"),每个value都是由几个小字符串组成的字典。

没有键被使用两次,我知道所有可能键的总超集。我将这些键值对添加到shelf通过线程,并且每次运行它时添加的键/值都会更改(这是预期的)。

我遇到的问题是shelve's可迭代/可见的键shelf.keys()数和不同的唯一键数key in shelf.keys()

这是我的代码。我首先初始化 things 和 load ids,这是所有可能键的列表。

import shelve 
from custom_code import *
MAIN_PATH = "/Users/myname/project_path/src/"
ids = list(set(load_list(MAIN_PATH + "id_list.pkl")))
c = c2 = 0
good_keys = []
bad_keys = []

然后我打开书架,计算我用 迭代的所有键的数量db.keys(),将“好”键添加到列表中。

db = shelve.open(MAIN_PATH + "first_3")
for k in db.keys():
    c2+=1
    good_keys+=[k]

然后,我检查每个可能的键以查看它是否在架子上,检查它是否存在于架子中,并执行与上述相同的操作。

for j in set(ids):
    if j in db.keys():
        c+=1
        bad_keys+=[j]

两个计数器cc2应该是相同的,但是这样做:

print("With `db.keys()`: {0}, with verifying from the list: {1}".format(c2, c))    

产量:

With `db.keys()`: 628, with verifying from the list: 669

然后,我查看存在bad_keys但不存在的键good_keys(即,从 收集db.keys())并选择一个示例。

odd_men_out = list( set(bad_keys).difference( set(good_keys) ) )
bad_key = odd_men_out[0] 
print(bad_key) # '84554'

然后我检查以下内容:

print(bad_key in db.keys()) # True
print(bad_key in db)  # True
print(db[bad_key]) # A dictionary of dictionaries that wraps ~12ish lines
print(bad_key in list(db.keys())) # False

注意最后一次检查。有谁知道给了什么?我以为shelves应该很容易,但它给了我完全的地狱。

也许不相关(但也许不是),当我让更多的条目堆积在书架上并尝试执行类似for k in db.keys()or的操作list(db.keys())时,我收到以下错误:

  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/_collections_abc.py", line 482, in __iter__
    yield from self._mapping
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/shelve.py", line 95, in __iter__
    for k in self.dict.keys():
SystemError: Negative size passed to PyBytes_FromStringAndSize

但仍然可以通过尝试所有可能的键来访问数据。显然那是因为我没有使用gdbm

4

1 回答 1

1

当我试图在我的架子上保存一些超过 1000 个元素的 numpy 数组时,它只会保存一些并完全跳过其他的,而不会产生错误。

显然这是在 Mac OSX 中使用 Shelve 时的一个问题(这里有一些错误报告(https://bugs.python.org/issue33074https://bugs.python.org/issue30388)。

我找到的唯一简单的解决方案是使用Pickle 而不是 Shelve

于 2021-11-10T15:07:10.333 回答