python shelve.open(...,flag =' n')不会创建一个空的货架

时间:2013-12-15 20:37:18

标签: python

我正在使用Python shelve模块和以下python版本: Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)] on win32。 shelve.open方法的flag参数描述为here

  

可选的flag参数与dbm.open()的flag参数具有相同的解释。

和dbm标志参数描述为here

  

'n'始终创建一个新的空数据库,打开以供阅读和编写

但是下面的程序没有像我预期的那样工作:

import shelve
import os
import os.path
import shutil
myshelvedir='C:\\testdir'
myshelvefile=os.path.join(myshelvedir,'myshelve')
os.mkdir(myshelvedir)
try:
    myshelve=shelve.open(myshelvefile)
    try:
        myshelve['key1']='value1'
        print(1,dict(myshelve))
    finally:
        myshelve.close()

    myshelve=shelve.open(myshelvefile,'n')
    try:
        myshelve['key2']='value2'
        print(2,dict(myshelve))
    finally:
        myshelve.close()

finally:
    shutil.rmtree(myshelvedir)

输出

1 {'key1': 'value1'}
2 {'key1': 'value1', 'key2': 'value2'}

对于我预期的第二行

2 {'key2': 'value2'}

因为搁置是用'n'标志打开的,所以打开后数据库应该是空的。

我错过了什么吗?

其他测试:

Python 3.0.1 (r301:69561, Feb 13 2009, 20:04:18) [MSC v.1500 32 bit (Intel)] on win32

我也得到了

2 {'key2': 'value2', 'key1': 'value1'}

Python 2.6.4 (r264:75706, Jun 27 2012, 05:45:50) [C] on sunos5

我得到了预期的

(2, {'key2': 'value2'})

也在 Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win 32

我得到了

(2, {'key2': 'value2'})

所以这是一个新功能或3

中的错误

1 个答案:

答案 0 :(得分:2)

我找到了http://bugs.python.org/issue18039

  

标题: dbm.open(...,flag =“n”)不起作用且不发出警告

给出了解释。

文档说shelve使用了一个可用的数据库接口。

http://docs.python.org/3/library/shelve.html

  

<强> 12.3。搁置 - Python对象持久性
  ...
  搁置。打开 (filename,flag ='c',protocol = None,writeback = False)
  打开一个持久的字典   ...
  可选的flag参数与dbm.open()的flag参数具有相同的解释   ...
  的 12.3.1。限制   选择使用哪个数据库包(例如dbm.ndbm或dbm.gnu)取决于可用的接口。因此,使用dbm直接打开数据库是不安全的。

并且'n'标志的作用类似于dbm.open

http://docs.python.org/3/library/dbm.html

  

<强> 12.5。 dbm - 与Unix“数据库”的接口
  dbm是DBM数据库变体的通用接口 - dbm.gnu或dbm.ndbm。如果没有安装这些模块,则将使用模块dbm.dumb中的缓慢但简单的实现   ...
  'n':始终创建一个新的空数据库,打开以供阅读和编写

但是这个n-flag的定义与n-flag的定义相矛盾,如果它退回到dbms.dumb

http://docs.python.org/3/library/dbm.html#module-dbm.gnu

  

<强> 12.5.1。 dbm.gnu - GNU对dbm的重新解释
  平台:Unix

http://docs.python.org/3/library/dbm.html#module-dbm.dumb

  

<强> 12.5.3。 dbm.dumb - 便携式DBM实现
  ...
  dbm.dumb.open(filename [,flag [,mode]])   ...   可选的flag参数当前被忽略;数据库始终打开以进行更新,如果不存在则会创建。

所以这可能不是安装了gnu.dbm库的Unix实现的问题(我无法访问Unix上的python 3来测试它)

由此我得出结论,python文档中有一些冲突的语句: 在安装了dbm库的unix系统上,python shelve将使用此dbm安装,此处'n'标志的工作方式如文档中所述。

如果找不到dbm安装(例如在Windows系统上),则将使用dbm.dumb模块,其中'n'的工作方式类似于'c'标志。