【问题标题】:How do I take integer keys in shelve?如何在搁置中获取整数键?
【发布时间】:2010-10-25 09:54:01
【问题描述】:

我想在搁置中存储一个整数键。但是当我尝试将整数键存储在搁置中时,它会给我一个错误

回溯(最近一次通话最后): 文件“./write.py”,第 12 行,在 数据[id] = {“Id”:id,“名称”:名称} 文件“/usr/lib/python2.5/shelve.py”,第 124 行,在 __setitem__ 中 self.dict[key] = f.getvalue() 文件“/usr/lib/python2.5/bsddb/__init__.py”,第 230 行,在 __setitem__ 中 _DeadlockWrap(wrapF) # self.db[key] = value DeadlockWrap 中的文件“/usr/lib/python2.5/bsddb/dbutils.py”,第 62 行 返回函数(*_args,**_kwargs) 文件“/usr/lib/python2.5/bsddb/__init__.py”,第 229 行,在 wrapF self.db[键] = 值 TypeError:整数键只允许用于 Recno 和 Queue DB

我的代码:

#!/usr/bin/python

import shelve

data = shelve.open("data.txt")

ans = 'y'
while ans == "y":
    id = input("Enter Id : ")
    name = raw_input("Enter name : ")

    data[id] = {"Id": id, "Name": name}

    ans = raw_input("Do you want to continue (y/n) ? : ")

data.close()

我的程序有问题还是搁置根本不支持整数键?


编辑 1:

在程序中,我试图将 Id 和 Name 的字典存储在另一个以 Id 作为键的字典中。然后尝试将其存储在文件中。

我需要将 Recno 或 Queue DB 与 shelve 一起使用吗?我是初学者,事情很混乱。

如果我的问题不清楚,请告诉我。

谢谢。

【问题讨论】:

  • "shelve 根本不支持整数键?"你为什么这么问?您的错误消息显示“仅允许 Recno 和 Queue DB 使用整数键”显然,Recno 和 Queue DB 支持整数键 。你在问什么?
  • @S.Lott 我想我需要用搁置来实现 Recno 或 Queue DB,我之所以问“我的程序有问题还是搁置根本不支持整数键?”
  • @S.Lott 我已经更新了我的问题。
  • 使用pickle 不能解决您的问题吗?

标签: python file-io dictionary shelve persistent-storage


【解决方案1】:

在您的示例中,数据库中的键始终是整数,因此将它们转换为字符串应该可以正常工作,

数据[str(id)] = {"Id": id, "Name": name}

我的测试代码

def shelve_some_data(filename):
    db = shelve.open(filename, flag="c")
    try:
        # note key has to be a string
        db[str(1)]    = "1 integer key that's been stringified" 
        db[str(2)]    = "2 integer key that's been stringified" 
        db[str(3)]    = "3 integer key that's been stringified" 
        db[str(10)]   = "10 integer key that's been stringified" 
    finally:
        db.close()

def whats_in(filename):
    db = shelve.open(filename, flag="r")
    for k in db:
        print("%s : %s" % (k, db[k]))
    return

filename = "spam.db"
shelve_some_data(filename)
whats_in(filename)

还有输出;它像字典一样工作,所以它没有排序。

2 : 2 integer key that's been stringified
10 : 10 integer key that's been stringified
1 : 1 integer key that's been stringified
3 : 3 integer key that's been stringified

【讨论】:

    【解决方案2】:

    搁置模块使用底层数据库包(例如 dbm、gdbm 或 bsddb)。

    “架子”是一个持久的、类似字典的对象。与“dbm”数据库的不同之处在于架子中的值(不是键!)本质上可以是任意的 Python 对象——pickle 模块可以处理的任何东西。这包括大多数类实例、递归数据类型和包含大量共享子对象的对象。键是普通字符串。 examples 部分为您提供证明。

    这应该可以。这是我在代码中所做的 -

    import shelve
    
    #Create shelve
    s = shelve.open('test_shelf.db')
    try:
        s['key1'] = { 'int': 10, 'float':9.5, 'string':'Sample data' }
    finally:
        s.close()
    
    #Access shelve
    s = shelve.open('test_shelf.db')
    try:
        existing = s['key1']
    finally:
        s.close()
    print existing
    

    更新:您可以尝试pickle 模块。它不是键值数据库,但您始终可以将数据结构构建为键值对,然后将其发送到pickle -

    如果您有一个对象 x 和一个已打开写入的文件对象 f,那么腌制该对象的最简单方法只需要一行代码

    pickle.dump(x, f)
    

    如果 f 是已打开读取的文件对象,则再次 unpickle 对象:

    x = pickle.load(f)
    

    我听说cPicklepickle 快很多。如果您有大量数据要存储,您可以试试这个。

    【讨论】:

    • 'key1' 不是字符串键吗?如何获取整数键?
    猜你喜欢
    • 1970-01-01
    • 2018-01-08
    • 2019-01-08
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 2010-09-05
    相关资源
    最近更新 更多