我正在为货架模块编写包装类,并且打算像字典一样使用它。这是代码:
import shelve
class MyShelve:
def __init__(self, filename='myshelve.db'):
self.s = shelve.open(filename)
def __del__(self):
self.s.close()
def __repr__(self):
return repr(self.s)
def __getitem__(self, k):
return self.s.get(k, None)
def __setitem__(self, k, v):
self.s[k] = v
直到我使用“ dict中的键”一词,一切似乎都可以正常工作。这是一个示例会话:
>>> d = {'1': 'One', '2': 'Two'}
>>> d
{'1': 'One', '2': 'Two'}
>>> '1' in d
True
>>> from myshelve import MyShelve
>>> s = MyShelve()
>>> s['1'] = 'One'
>>> s['2'] = 'Two'
>>> s
{'1': 'One', '2': 'Two'}
>>> '1' in s.s
True
>>> '1' in s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "myshelve.py", line 15, in __getitem__
return self.s.get(k, None)
File "/usr/lib64/python2.7/shelve.py", line 113, in get
if key in self.dict:
File "/usr/lib64/python2.7/_abcoll.py", line 369, in __contains__
self[key]
File "/usr/lib64/python2.7/bsddb/__init__.py", line 270, in __getitem__
return _DeadlockWrap(lambda: self.db[key]) # self.db[key]
File "/usr/lib64/python2.7/bsddb/dbutils.py", line 68, in DeadlockWrap
return function(*_args, **_kwargs)
File "/usr/lib64/python2.7/bsddb/__init__.py", line 270, in <lambda>
return _DeadlockWrap(lambda: self.db[key]) # self.db[key]
TypeError: Integer keys only allowed for Recno and Queue DB's
我究竟做错了什么?
首先,始终要继承自object
。它将使您免于以后的麻烦。其次,您需要使用__contains__
。第三,当使用__contains__
或__getitem__
或任何dunder方法处理此事时,请确保使用异常,即try-except块。这是您要寻找的样本:
class MyShelve(object):
def __init__(self, filename='myshelve.db'):
self.s = shelve.open(filename)
def __del__(self):
self.s.close()
def __repr__(self):
return repr(self.s)
def __getitem__(self, item):
return self.s.get(item, False)
def __contains__(self, item):
try:
return item in self.s
except TypeError:
return False
def __setitem__(self, k, v):
self.s[k] = v
演示:
In[3]: from shelving import MyShelve
In[4]: s = MyShelve()
In[5]: s['1'] = 'One'
In[6]: s['2'] = 'Two'
In[7]: '1' in s
Out[7]: True
请注意,没有异常块,表达式3 in s
将对此求值:
Traceback (most recent call last):
(...)
TypeError: gdbm key must be string, not int
事后看来,在这种情况下,最好使用带有预配置值的函数而不是使用类,因为这样会覆盖很多东西,这将浪费您的时间。此外,使用上下文管理器更容易使用,该上下文管理器具有返回文件对象的功能,而不是具有封装文件对象的类(因为当您打开文件架时,实际上是在创建文件)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句