python的搁置模块有最大尺寸吗?

时间:2013-05-01 21:24:54

标签: python shelve

我试图打开超过一定大小的搁置持久文件时遇到此异常,这实际上非常小(<1MB),但我不确定确切的数字在哪里。现在,我知道pickle有点像python的私生子,搁置并不被认为是一个特别强大的解决方案,但它恰好解决了我的问题(理论上),我无法找到原因这个例外。

Traceback (most recent call last):
  File "test_shelve.py", line 27, in <module>
    print len(f.keys())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shelve.py", line 101, in keys
    return self.dict.keys()
SystemError: Negative size passed to PyString_FromStringAndSize

我可以一致地重现它,但我在谷歌上找不到太多东西。这是一个可以重现的脚本。

import shelve
import random
import string
import pprint

f = shelve.open('test')
# f = {}

def rand_list(list_size=20, str_size=40):
    return [''.join([random.choice(string.ascii_uppercase + string.digits) for j in range(str_size)]) for i in range(list_size)]

def recursive_dict(depth=3):
    if depth==0:
        return rand_list()
    else:
        d = {}
        for k in rand_list():
            d[k] = recursive_dict(depth-1)
        return d

for k,v in recursive_dict(2).iteritems():
    f[k] = v

f.close()

f = shelve.open('test')
print len(f.keys())

2 个答案:

答案 0 :(得分:2)

如果我将深度从2更改为1,或者如果我在python 3下运行(在修复print语句并使用items()而不是iteritems()后),则代码“有效” 。但是,在迭代recursive_dict()的返回值时,键列表显然不是找到的键集。

shelve文档中的以下限制可能适用(强调我的):

  

选择使用哪个数据库包(例如dbm,gdbm或bsddb)取决于可用的接口。因此,使用dbm直接打开数据库是不安全的。 数据库(不幸的是)受到dbm的限制,如果使用的话 - 这意味着存储在数据库中的对象的(腌制表示)应该相当小,并且在极少数情况下,密钥冲突可能导致数据库拒绝更新。

答案 1 :(得分:2)

关于错误本身:

  

在网络上传播的想法是数据大小超过最大   该机器上可能的整数(最大的32位(带符号)整数)   是2 147 483 647),被Python解释为负面大小。

您的代码与2.7.3一起运行,因此可能是一个固定的错误。