Shelve 在 Python 3.3 中给出了 AttributeError for hello world example using the "with shelve.open" syntax,但并非没有它

Shelve gives AttributeError in Python 3.3 for hello world example using the "with shelve.open" syntax, but not without it

我正在尝试将 shelve 与 Python 3.3 一起使用。建议使用 with shelve.open('spam.db') as db:... 语法来确保我们关闭 "connection"。但是,当我尝试它时,出现以下错误 AttributeError: __exit__。是什么赋予了?有什么想法吗?这里有很多类似的问题,虽然找不到令人满意的解决方案。以下显示了我到目前为止所做的尝试:

以下失败:

import shelve
with shelve.open('spam.db') as db:
    db['key'] = 'value'
    print(db['key'])

错误信息:

Traceback (most recent call last):
  File "D:\arbitrary_path_to_script\nf_shelve_test.py", line 3, in <module>
    with shelve.open('spam.db') as db:
AttributeError: __exit__
[Finished in 0.1s with exit code 1]

以下作品:

import shelve
db = shelve.open('spam.db')
db['key'] = 'value'
print(db['key'])
db.close()

并输出预期的:

value
[Finished in 0.1s]

正在打印搁置模块路径

import shelve
print(shelve)

地点:

<module 'shelve' from 'C:\Python33\lib\shelve.py'>
[Finished in 0.1s]

In Python 3.3 shelve.open() 不是上下文管理器,不能在 with 语句中使用。 with 语句期望有 __enter__ and __exit__ methods;你看到的错误是因为没有这样的方法。

您可以在此处使用 contextlib.closing()shelve.open() 结果包装在上下文管理器中:

from contextlib import closing

with closing(shelve.open('spam.db')) as db:

或者,升级到 Python 3.4,其中所需的上下文管理器方法已添加到 shelve.open() 的 return 值中。来自 shelve.Shelve documentation:

Changed in version 3.4: Added context manager support.

Shelf 不是 Python 3.3 中的上下文管理器;此功能是在 3.4 中引入的。如果您需要支持 3.3,则需要在 finally 块中使用 contextlib.closing 或明确的 close。我推荐 contextlib.closing.

import contextlib

with contextlib.closing(shelve.open('spam.db')) as db:
    do_whatever_with(db)