我正在使用python的内置搁置模块来管理一些简单的词典。我遇到的问题是我想使用with shelve.open(filename) as f:
,但当我尝试它时声称DbfilenameShelf没有属性__exit__
。
所以,我猜测最简单的方法是将它包装在另一个类中并向该包装器添加一个__exit__
函数。我试过这个:
class Wrapper(shelve.DbfilenameShelf):
def __exit__(self):
self.close()
def __init__(self, filename, writeback=False):
shelve.DbfilenameShelf.__init__(self, filename, flag='c', protocol=None, writeback=False)
但是当我试图像这样实例化包装器时:wrapped = Wrapper(filename)
它告诉我我给它一个无效的参数。
请求错误:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 5, in __init__
File "C:\Python27\Lib\shelve.py", line 223, in __init__
Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback)
File "C:\Python27\Lib\anydbm.py", line 85, in open
return mod.open(file, flag, mode)
File "C:\Python27\Lib\dbhash.py", line 18, in open
return bsddb.hashopen(file, flag, mode)
File "C:\Python27\Lib\bsddb\__init__.py", line 364, in hashopen
d.open(file, db.DB_HASH, flags, mode)
DBInvalidArgError: (22, 'Invalid argument')
答案 0 :(得分:12)
不要将其子类化。 Python附带了一个自动调用close()
,contextlib.closing
:
from contextlib import closing
with closing(shelve.open(filename)) as f:
# your 'with' block here
将自动调用close()
块末尾shelve.open(filename)
返回的对象的with
方法。
答案 1 :(得分:2)
你正在对错误的东西进行子类化并错过了__enter__
方法。你可能想要这个:
class contextShelf(shelve.shelve):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_trace):
self.close()
由于您要添加方法,但未更改__init__
签名或添加任何额外步骤,因此您无需重新定义__init__
。基类“__init__
将自动调用。