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

ITA*_*ITA 5 python shelve python-3.7

shelve只读模式坏了吗?文档说该flag参数的工作原理如中所述,dbm.open所以我认为如果我以读取模式打开,我不应该能够更改搁置对象。

\n\n

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

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

接下来我将用 和 打开它flag=\'r\',只是writeback=False为了确定一下。但我可以修改对象。

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

只是为了确认,再次打开并打印它表明该对象确实发生了变化:

\n\n
>>> with shelve.open(\'testdata\', flag=\'r\', writeback=False) as shelf:\n...     for k, v in shelf.items():\n...             print(\'Key: \', k, \' Value: \', v)\n... \nKey:  one  Value:  2222\nKey:  two  Value:  1111\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

\xe2\x80\x94

\n\n

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

\n\n
Python 3.6.7 (default, Oct 22 2018, 11:32:17)\n[GCC 8.2.0] on linux\nType "help", "copyright", "credits" or "license" for more information.\n
Run Code Online (Sandbox Code Playgroud)\n\n

以及在 MacOS 上:

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

Ubuntu 18.04 上的 3.7.2 出现问题。如果文件名具有扩展名“.db”,则会给出:

\n\n
dbm.error: db type is dbm.gnu, but the module is not available\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果没有扩展名,只读模式将不起作用。

\n

ITA*_*ITA 0

我将其追溯到使用ndbm或实现gdbm在使用或模块打开的发行版上,可以按预期工作。但是,(至少在 Ubuntu 18.04 和 Python 3.7.2 by Anaconda 上)如果正在使用,则行为如问题中的上述,并且只读标志不会阻止写入。dumbndbmgdbmflag='r'dumb

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