Python`搁置`只读模式不起作用

Posted

技术标签:

【中文标题】Python`搁置`只读模式不起作用【英文标题】:Python `shelve` read-only mode is not working 【发布时间】:2019-03-23 23:32:22 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

万一有人试图在 VirtualBox 中的共享文件夹上使用 Shelve:它会失败。由于 gdm 模块尝试创建具有 x666 权限的数据库文件,并且似乎只能在共享文件夹中创建具有 0x770 权限的文件。要查看这是否是您的问题,请尝试在 /tmp 中创建您的数据库。

【讨论】:

以上是关于Python`搁置`只读模式不起作用的主要内容,如果未能解决你的问题,请参考以下文章

将属性更改为只读不起作用

为啥我们不能在 TypeScript 类中定义一个 const 字段,为啥静态只读不起作用?

“富文本编辑器”只读不起作用

渲染器使单元格相对于其他单元格值只读后的 JQuery handsontable - 不起作用

Python-Selenium:剪贴板功能(ctrl + c)在 Firefox 无头模式下不起作用

Python 3.1.1 中的搁置模块