Shelve在Python 3.3中为使用"和shelve.open"的hello world示例提供了AttributeError。语法,但不是没有它

时间:2015-05-25 18:23:15

标签: python python-3.x with-statement shelve

我试图在Python 3.3中使用shelve。建议使用with shelve.open('spam.db') as db:...语法确保我们关闭"连接"。但是,当我尝试它时,我收到以下错误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]

2 个答案:

答案 0 :(得分:4)

在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()的返回值。来自shelve.Shelve documentation

  

在3.4版中更改:添加了上下文管理器支持。

答案 1 :(得分:3)

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)