【问题标题】:Python 2.7.2 shelve fails on OSXPython 2.7.2 搁置在 OSX 上失败
【发布时间】:2013-09-22 23:32:43
【问题描述】:

使用 Python 2.7.2 上的 shelve 标准库,我编写了一个极其简单的测试来创建一个持久数据文件,然后立即打开它进行打印:

import os
import shelve

shelf_filename = str(__file__.split('.')[0] + '.dat')

#delete the shelf file if it exists already.
try:
    os.remove(shelf_filename)
    print "DELETED LEFTOVER SHELF FILE", shelf_filename
except OSError:
    pass

#create a new shelf, write some data, and flush it to disk
shelf_handle = shelve.open(shelf_filename)
print "OPENED", shelf_filename, "WITH SHELF"
shelf_handle['foo'] = 'bar'
shelf_handle.close()
print "FLUSHED AND CLOSED THE SHELF"

#re-open the shelf we just wrote, read/print the data, and close it
shelf_handle = shelve.open(shelf_filename)
print "RE-OPENED", shelf_filename, "WITH SHELF"
print 'foo:', shelf_handle.get('foo')
shelf_handle.close()

#delete the shelf file
os.remove(shelf_filename)

但是,当它尝试重新打开它刚刚创建的书架时,此脚本意外失败:

DELETED LEFTOVER SHELF FILE shelve_test.dat
OPENED shelve_test.dat WITH SHELF
FLUSHED AND CLOSED THE SHELF
Traceback (most recent call last):
  File "shelve_test.py", line 21, in <module>
    shelf_handle = shelve.open(shelf_filename)
  File ".../shelve.py", line 239, in open
    return DbfilenameShelf(filename, flag, protocol, writeback)
  File ".../shelve.py", line 223, in __init__
    Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback)
  File ".../anydbm.py", line 82, in open
    raise error, "db type could not be determined"
anydbm.error: db type could not be determined

这是关于搁置的最基本的可能用法,所以我真的不明白我错过了什么,而且我一直在按照文档进行操作。有一点搁置经验的人可以告诉我这是怎么回事吗?

更新:这个脚本显然适用于某些平台而不是其他平台,这对于 Python 标准库来说确实有点令人惊讶。绝对确认这不起作用:

Python 2.7.2 (default, May 15 2013, 13:46:05) 
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.28)] on darwin

【问题讨论】:

  • 您的代码对我来说按原样运行,您运行的是什么版本?编辑:我也不明白你为什么要使用书架来删除它们。
  • hooo boy...这对于标准库来说真的很糟糕。在原始问题中添加了我的操作系统和 Python 版本详细信息。您的版本详细信息是什么?
  • 重新删除架子:这只是为了说明,架子正在创建文件。

标签: python shelve


【解决方案1】:

此版本的 Python shelve 使用了已弃用的 dbm 包,可以通过指定不同的 dbm 来解决此问题,如下所示:

import anydbm
anydbm._defaultmod = __import__('dumbdbm')

如果将这两行添加到上面的脚本中,那么一切都会按预期进行。这确实需要搁置。

【讨论】:

  • 不修改脚本可以修复吗?
【解决方案2】:

shelve 不希望您在文件名上指定扩展名。相反,它根据用于创建文件的 db 为文件提供扩展名。

因此,当您调用shelve.open("shelve_test.dat") 时,您正在创建一个shelve 期望使用dumbdbm 创建的文件,但它是使用不同(更好的)数据库管理器创建的。

相反,您应该调用shelve.open("shelve_test"),这样shelve 可以选择使用正确的扩展名保存文件。这也适用于打开已创建的文件。

【讨论】:

  • P.S.:为了记录,dumbdbm 是效率最低的数据库。无论您的计算机默认使用什么,都可能是它所拥有的最高效的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 2018-09-24
  • 1970-01-01
相关资源
最近更新 更多