4

我正在使用 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')    
4

2 回答 2

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

于 2011-09-20T18:17:46.250 回答
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__将被自动调用。

于 2011-09-20T18:17:11.920 回答