3

実際にはかなり小さい(< 1MB)特定のサイズを超える保留永続化ファイルを開こうとすると、この例外が発生しますが、正確な数がどこにあるのかわかりません。今、私は pickle が python のろくでなしの子のようなものであり、shelve が特に堅牢なソリューションとは考えられていないことを知っていますが、それはたまたま (理論的には) 私の問題を素晴らしく解決し、その理由を見つけることができませんでしたこの例外。

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())
4

2 に答える 2

2

print深さを 2 から 1 に変更した場合、または python 3 で実行した場合 (ステートメントを修正し、items()代わりにを使用した後) 、コードは「機能します」iteritems()。ただし、キーのリストは、 の戻り値を反復処理するときに見つかったキーのセットではないことは明らかですrecursive_dict()

ドキュメントからの次の制限shelveが適用される場合があります(私のものを強調します):

使用するデータベース パッケージ (dbm、gdbm、bsddb など) の選択は、使用可能なインターフェースによって異なります。したがって、dbm を使用してデータベースを直接開くのは安全ではありません。データベースも (残念ながら) dbm の制限の対象となります。これは、データベースに格納されているオブジェクト (の pickle 化された表現) がかなり小さいことを意味し、まれにキーの衝突によってデータベースが更新を拒否します。

于 2013-05-01T21:49:25.437 に答える