2

私はPython3を使用しています。shelveドキュメントでは、の永続バージョンとしてアドバタイズされていますdict。ただし、私の使用法ではshelve、タプルをキーとして許可していませんが、dictは次のことを許可しています。

import shelve
def tryShelve():
    db = shelve.open("shelvefile")
    db["word1"] = 1
    db[("word1", "word2")] = 15

tryShelve()

このエラーが発生します:

Traceback (most recent call last):
  File "<pyshell#41>", line 1, in <module>
    tryShelve()
  File "<pyshell#40>", line 4, in tryShelve
    db[("word1", "word2")] = 15
  File "C:\Python32\lib\shelve.py", line 125, in __setitem__
    self.dict[key.encode(self.keyencoding)] = f.getvalue()
AttributeError: 'tuple' object has no attribute 'encode'
4

4 に答える 4

4

モジュールドキュメントshelve最初の段落:

「棚」は、永続的な辞書のようなオブジェクトです。「dbm」データベースとの違いは、シェルフ内の値(キーではありません!)が本質的に任意のPythonオブジェクト、つまりpickleモジュールが処理できるものであれば何でもかまいません。これには、ほとんどのクラスインスタンス、再帰データ型、および多くの共有サブオブジェクトを含むオブジェクトが含まれます。キーは通常の文字列です。

[強調鉱山]

yamlモジュールはタプルをキーとして許可します:

>>> d = {}
>>> d["word1"] = 1
>>> d[("word1", "word2")] = 15
>>> import yaml
>>> yaml.dump(d)
'word1: 1\n? !!python/tuple [word1, word2]\n: 15\n'
>>> yaml.load(_)
{('word1', 'word2'): 15, 'word1': 1}
于 2011-03-20T09:11:47.837 に答える
2

タプルは、どちらのPython2.7.1バージョンでもキーとして機能しませんshelve。2.7.1のドキュメントでは、ActiveStatePersistentディクショナリレシピを確認することを提案しています。私がテストしたところ、'csv'フォーマットではなく、フォーマットを使用したサンプルコードに示されているように、キーとしてタプルを使用して機能しているように見えました'jason'(そして私は試しませんでした'pickle')。レシピを見れば、「フォーマット」の意味がわかります。

于 2011-03-20T09:20:51.073 に答える
1

棚はファイルに書き込むためにタプルをシリアル化できないように見えます。代替案として
検討してください。pickle

于 2011-03-20T09:11:24.013 に答える
1

タプルをシェルフのキーとして使用する前に、タプルを文字列に変換するためにdumps使用できます。loadsまたは、タプルにリテラルのみが含まれている場合は、を使用repr(your_tuple)して文字列表現を取得し、を使用してタプルに変換し直すことができますliteral_eval

変換をより便利にするために、サブクラス化Shelfしてオーバーライド__getitem____setitem__、アクセス時に自動的に変換を行うことができます。

于 2011-03-20T09:14:56.433 に答える