Python`shelve`只读模式不起作用

时间:2019-03-23 23:32:22

标签: python python-3.7 shelve

shelve的只读模式是否损坏?文档说flag参数按照dbm.open的说明工作,所以我认为如果我以读取模式打开,我将无法更改搁置对象。

页面here似乎还建议修改以只读方式打开的搁置对象会引发异常。但我仍然可以执行以下操作:

Python 3.7.2 (default, Dec 29 2018, 06:19:36) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import shelve
>>> with shelve.open('testdata') as shelf:
...      shelf['two'] = 2222
...      shelf['one'] = 1111
... 

接下来,为了确定,我将使用flag='r'writeback=False打开它。但是我能够修改对象。

>>> with shelve.open('testdata', flag='r', writeback=False) as shelf:
...     for k, v in shelf.items():
...             print('Key: ', k, ' Value: ', v)
...     shelf['two'] = 1111
...     shelf['one'] = 2222
... 
Key:  one  Value:  1111
Key:  two  Value:  2222

只需确认一下,再次打开并打印出来,便表明该对象确实发生了变化:

>>> with shelve.open('testdata', flag='r', writeback=False) as shelf:
...     for k, v in shelf.items():
...             print('Key: ', k, ' Value: ', v)
... 
Key:  one  Value:  2222
Key:  two  Value:  1111

我想念什么?这可能与在不同系统上dbm的选择/实现有关吗?在链接的页面上运行代码也不会导致:ERROR: cannot add item to database,如页面所示。

更新:链接页面中的代码按预期工作,即引发错误,当我使用较早版本的Python时,

Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

以及在MacOS上:

Python 3.6.5 |Anaconda, Inc.| (default, Apr 26 2018, 08:42:37)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

在Ubuntu 18.04上使用3.7.2时,一切崩溃了。如果文件名的扩展名为“ .db”,则给出:

dbm.error: db type is dbm.gnu, but the module is not available

,并且没有扩展名,只读模式不起作用。

2 个答案:

答案 0 :(得分:0)

我追溯到在implementation中使用ndbmgdbmdumb。在使用ndbmgdbm模块的发行版中,以flag='r'打开会按预期工作。但是,(至少在Anaconda使用Python 3.7.2的Ubuntu 18.04上,如果使用了dumb,则行为与问题中的上述行为相同,并且只读标志不会阻止写入。

由于某种原因,Anaconda没有利用系统上安装的python3-gdbm。如here所述,将库从系统文件复制到anaconda环境解决了该问题。

答案 1 :(得分:0)

只有一个偶然的机会,有人正在/正在尝试在VirtualBox的共享文件夹上使用Shelve:它将失败。由于gdm模块尝试创建权限为x666的数据库文件,因此似乎只能在共享文件夹中创建权限为0x770的文件。要查看这是否是您的问题,请尝试在/ tmp中建立数据库。