I'm trying to use shelve with Python 3.3. It is recommended to use the with shelve.open('spam.db') as db:...
syntax to ensure we close the "connection". However, when I try it I get the following error AttributeError: __exit__
. What gives? Any thoughts? Many similar questions here, although couldn't find a satisfying solution. The following shows what I have attempted thus far:
The following fails:
import shelve
with shelve.open('spam.db') as db:
db['key'] = 'value'
print(db['key'])
Error message:
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]
The following works:
import shelve
db = shelve.open('spam.db')
db['key'] = 'value'
print(db['key'])
db.close()
And outputs the expected:
value
[Finished in 0.1s]
Printing the shelve module path
import shelve
print(shelve)
Location:
<module 'shelve' from 'C:\\Python33\\lib\\shelve.py'>
[Finished in 0.1s]
In Python 3.3 shelve.open()
is not a context manager and cannot be used in a with
statement. The with
statement expects there to be __enter__
and __exit__
methods ; the error you see is because there are no such methods.
You can use contextlib.closing()
to wrap the shelve.open()
result in a context manager here:
from contextlib import closing
with closing(shelve.open('spam.db')) as db:
Alternatively, upgrade to Python 3.4, where the required context manager methods were added to the return value of shelve.open()
. From the shelve.Shelve
documentation :
Changed in version 3.4 : Added context manager support.
Shelf
isn't a context manager in Python 3.3; this functionality was introduced in 3.4. If you need to support 3.3, you'll need to use contextlib.closing
or an explicit close
in a finally block. I recommend contextlib.closing
.
import contextlib
with contextlib.closing(shelve.open('spam.db')) as db:
do_whatever_with(db)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.